Android 学习笔记:Navigation Drawer

laylout文件:
<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">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="1dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

 

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:textColor="#fff"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

 

 

package com.example.navigationdemo;

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
    private String[] mPlanetTiles;
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mPlanetTiles = getResources().getStringArray(R.array.planets_array);
        mDrawerLayout= (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList= (ListView) findViewById(R.id.left_drawer);
        mDrawerList.setAdapter(new ArrayAdapter<String>(this,R.layout.drawer_list_item,mPlanetTiles));
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    private class DrawerItemClickListener implements ListView.OnItemClickListener{

        @Override
        public void onItemClick(AdapterView parent, View view, int position,
                long id) {
            // TODO Auto-generated method stub
            selectItem(position);
        }
        
    }
    public void selectItem(int position) {
        // TODO Auto-generated method stub
        Log.d("",position+"");
    }
}

 到了这一步就基本可用跑起来了,运行看看效果:

点两下:

不过还有点问题,左边的侧滑栏并不会在点击后自动收回。我们继续。

 

 

继续增加下面的代码:

public void selectItem(int position) {
        // Create a new fragment and specify the planet to show based on position
        Log.d("",position+"");
        Fragment fragment = new PlanetFragment();
        Bundle args = new Bundle();
        args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
        fragment.setArguments(args);
        // Insert the fragment by replacing any existing fragment
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction()//此函数返回一个FragmentTransactiond对象,用来开始一系列对Fragments的操作
                       .replace(R.id.content_frame, fragment)//Replace an existing fragment that was added to a container
                                                                //依旧返回返回一个FragmentTransactiond对象
                       .commit();
     // Highlight the selected item, update the title, and close the drawer
        mDrawerList.setItemChecked(position, true);
        setTitle(mPlanetTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }
    public static class PlanetFragment extends Fragment {
        public static final String ARG_PLANET_NUMBER = "planet_number";

        public PlanetFragment() {
            // Empty constructor required for fragment subclasses
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
                 View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
          //作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化
int i = getArguments().getInt(ARG_PLANET_NUMBER); String planet = getResources().getStringArray(R.array.planets_array)[i]; int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()), "drawable", getActivity().getPackageName()); ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId); getActivity().setTitle(planet); return rootView; }

同样,增加一个fragment_planet的布局:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    android:gravity="center"
    android:padding="32dp" />

当你点击了listview中的项目时,系统就会setOnItemClickListener()函数设定的OnItemClickListener 类里的onItemClick()函数。

上面这段代码的作用就是在点击了Drawer对应项目之后,新生成一个Fragment,将现有的替换掉。然后关闭Drawer。

官方demo中用的是几颗行星的图片,所以对应变量也是,我随便放了几张图片上去:

不过还是有点小问题,程序刚运行的时候,并没有任何fragment被载入,程序是一片空白。

 接下来要实现的效果是点击actionbar上的图标来展示drawer,同时还有一个指示的动画。

我们需要使用ActionBarDrawerToggle的类:

This class provides a handy way to tie together the functionality of DrawerLayout and the framework ActionBar to implement the recommended design for navigation drawers.

To use ActionBarDrawerToggle, create one in your Activity and call through to the following methods corresponding to your Activity callbacks:

Call syncState() from your Activity's onPostCreate to synchronize the indicator with the state of the linked DrawerLayout after onRestoreInstanceState has occurred.

ActionBarDrawerToggle can be used directly as a DrawerLayout.DrawerListener, or if you are already providing your own listener, call through to each of the listener methods from your own.

在activity的OnCreate函数里加入:

getActionBar().setDisplayHomeAsUpEnabled(true);  显示向上箭头 
getActionBar().setHomeButtonEnabled(true);让程序图标可以点击。

接下来在,activity里重写一个函数,用来在点击图标后drawer。

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
          return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

其余的应该都是保持、恢复程序状态的函数。

ActionBarDrawerToggle也提供了onDrawerClosed(View drawerView) onDrawerOpened(View drawerView) 的函数,动态改变actionbar的标题就是用这个。比较有技巧的一点是,每次改变标题的时候需要把之前的标题保存下来。

项目代码参考:http://developer.android.com/training/implementing-navigation/nav-drawer.html

 

 

 

posted @ 2014-03-07 11:42  jzlikewei  阅读(650)  评论(0编辑  收藏  举报