web-dev-qa-db-ja.com

ナビゲーションドロワー:リストビューにヘッダーを追加する

新しいナビゲーションドロワーオブジェクトを使用してプロジェクトを作成しました。

メニューのレイアウトをカスタマイズし、TextView、ImageViewなどの別のオブジェクトを追加したいと思います。最初に、1つだけのリストビューで構成されるデフォルトのレイアウトを、2つまたは3つのヘッダーをリストビュー。

今日、「addHeaderView」を使用しようとしましたが、これは1つのヘッダーを追加するためにのみ使用することが可能だと思います。

ヘッダーを追加してレイアウトメニューを実際にカスタマイズするにはどうすればよいですか?開発者APIから、「Android.support.v4.widget.DrawerLayout」の下では2つの子しか許可されていないようです。

これが今日の私のレイアウトのキャプチャです。

Navigation Drawer Headers in listview

そして、ここに私が作成したいキャプチャがあります:

Navigation Drawer Headers in listview

これが私のMainActivityのコードの一部です:

public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;

private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTitle = mDrawerTitle = getTitle();
    mPlanetTitles = getResources().getStringArray(R.array.planets_array);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    // Declaration of the 2 listview's 
    mDrawerList = (ListView) findViewById(R.id.dernieres_news);

    LayoutInflater inflater = getLayoutInflater();

    // Add header news title
    ViewGroup header_news = (ViewGroup)inflater.inflate(R.layout.header_dernieres_news, mDrawerList, false);
    mDrawerList.addHeaderView(header_news, null, false);

    // set a custom shadow that overlays the main content when the drawer opens
    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

    String[] names=new String[]{"Title 1", "Title 2", "Title 3", "Title 4", "Title 5"};

    /*Array of Images*/
    int[] image = new int[] {R.drawable.ic_action_feed, R.drawable.ic_action_feed, R.drawable.ic_action_feed, R.drawable.ic_action_feed, R.drawable.ic_action_feed};

    List<HashMap<String, String>> listinfo = new ArrayList<HashMap<String, String>>();
    listinfo.clear();
    for(int i=0;i<5;i++){
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("name", names[i]);
        hm.put("image", Integer.toString(image[i]));
        listinfo.add(hm);
    }

    // Keys used in Hashmap
    String[] from = { "image", "name" };
    int[] to = { R.id.img, R.id.txt };
    SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), listinfo, R.layout.drawer_list_item, from, to);
    mDrawerList.setAdapter(adapter);

    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    // enable ActionBar app icon to behave as action to toggle nav drawer
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    // ActionBarDrawerToggle ties together the the proper interactions
    // between the sliding drawer and the action bar app icon
    mDrawerToggle = new ActionBarDrawerToggle(
            this,                  /* Host Activity */
            mDrawerLayout,         /* DrawerLayout object */
            R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
            R.string.drawer_open,  /* "open drawer" description for accessibility */
            R.string.drawer_close  /* "close drawer" description for accessibility */
            ) {
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(mTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(mDrawerTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    if (savedInstanceState == null) {
        selectItem(0);
    }
}

そしてactivity_main.xmlのコード:

<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent" >

<FrameLayout
    Android:id="@+id/content_frame"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" />


    <ListView
        Android:id="@+id/dernieres_news"
        Android:layout_width="240dp"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:background="#F3F3F4"
        Android:choiceMode="singleChoice"
        Android:divider="#E3E9E3"
        Android:dividerHeight="1dp" />
15
wawanopoulos

他のListViewに見出しを追加するのと同じ方法で、ListAdapterに見出し行と詳細行を返すように指示します。低レベルでは、これにはListAdaptergetViewTypeCount()getItemViewType()などのメソッドをオーバーライドすることと、getView()に行タイプの違いを認識させることが含まれます。または、 https://github.com/emilsjolander/StickyListHeaders または http://code.google.com/p/Android-amazing-listviewのような既存の高レベルの実装を使用します/ またはAndroid listview headersを検索したときに見つかった他のいずれか。

8
CommonsWare

他の答えは正しいです。

2つのタイプのアイテムを含むようにビューをカスタマイズする本当に良い例を見つけました:menu sectionおよびmenu item。もちろん、好きなように変更することができます。

この例には、ナビゲーションドロワーを持つすべてのアクティビティが継承する抽象アクティビティクラスの実装も含まれています。

http://www.michenux.net/Android-navigation-drawer-748.html

8
Michael

BaseAdapterをサブクラス化し、ListViewでSimpleAdapterの代わりにこれを使用する必要があります。

アダプターに詰め込みデータを提供します。追加データはタイトルです。タイトルとリストアイテム自体は、同じ共通クラスのメンバーになります。次に、アダプターで、実際のビューがタイトルであるかアイテムであるかをデータ項目に基づいて決定し、それに応じてそれを拡張します。

更新:

これは良い例です: http://w2davids.wordpress.com/Android-sectioned-headers-in-listviews/

これにより、以前のアプリでこれまで使用していたソリューションとは異なり、タイトルとデータアイテムが実際に分離され、convertViewが正しく使用されます。

1
Herrbert74