1. 程式人生 > >Android左側選單欄之DrawerLayout+Fragment

Android左側選單欄之DrawerLayout+Fragment

關於DrawerLayout,官方網站給出了相當好的案例

不過對於版本的限定,要求比較高

不過去掉ActionBarDrawerToggle,更換android.app.Fragment

就可以相容到8了

老規矩,先看效果圖,不然浪費大家的時間就是罪過了


看目錄結構:


fragment中的內容都一樣,如果在實際開發中,下面的實現有損效能,各位可以自己優化下

先看佈局檔案activity_main.xml:

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/body_background" >

    <RelativeLayout
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#293236"
        android:gravity="center_vertical" >

        <Button
            android:id="@+id/left"
            style="@style/ButtonHeadStyle"
            android:text="Menu" />

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:textColor="#FFF"
            android:textSize="18sp" />
    </RelativeLayout>

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/header" >

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

        <ListView
            android:id="@+id/drawer_list"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="left"
            android:background="#111"
            android:choiceMode="singleChoice"
            android:divider="@android:color/transparent"
            android:dividerHeight="0dp" />
    </android.support.v4.widget.DrawerLayout>

</RelativeLayout>

drawer_list_item.xml,此處用的是官方Demo,不過修改了一些配置:
<?xml version="1.0" encoding="utf-8"?>
<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:background="?attr/activatedBackgroundIndicator"
    android:gravity="center_vertical"
    android:minHeight="?attr/listPreferredItemHeightSmall"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:textAppearance="?attr/textAppearanceListItemSmall"
    android:textColor="#fff" />

專案目錄截圖少了點檔案,抱歉,在values檔案中建立attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="AppTheme">

        <!-- Drawable used as a background for activated items. -->
        <attr name="activatedBackgroundIndicator" format="reference" />

        <!-- Attributes below are needed to support the navigation drawer on Android 3.x. -->
        <!-- A smaller, sleeker list item height. -->
        <attr name="listPreferredItemHeightSmall" format="dimension" />

        <!-- The preferred TextAppearance for the primary text of small list items. -->
        <attr name="textAppearanceListItemSmall" format="reference" />
    </declare-styleable>

</resources>

在values-v11目錄中的style.xml檔案中新增如下資訊:
<resources>

    <!--
        Base application theme for API 11+. This theme completely replaces
        AppBaseTheme from res/values/styles.xml on API 11+ devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
        <!-- API 11 theme customizations can go here. -->
        <item name="textAppearanceListItemSmall">@style/DrawerMenu</item>
        <item name="activatedBackgroundIndicator">@android:color/transparent</item>
        <item name="listPreferredItemHeightSmall">48dp</item>
    </style>

    <style name="DrawerMenu">
        <item name="android:textSize">16sp</item>
        <item name="android:textStyle">bold</item>
        <item name="android:textColor">@android:color/black</item>
    </style>
</resources>

在values-v14目錄中的style.xml中新增如下資訊:
<resources>

    <!--
        Base application theme for API 14+. This theme completely replaces
        AppBaseTheme from BOTH res/values/styles.xml and
        res/values-v11/styles.xml on API 14+ devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- API 14 theme customizations can go here. -->
        <item name="textAppearanceListItemSmall">?android:attr/textAppearanceListItemSmall</item>
        <item name="activatedBackgroundIndicator">?android:attr/activatedBackgroundIndicator</item>
        <item name="listPreferredItemHeightSmall">?android:attr/listPreferredItemHeightSmall</item>
    </style>

</resources>

fragment_home.xml檔案:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

</LinearLayout>

MainActivity.java:
/**
 * DrawerLayout右側選單欄
 * 相容到8
 * @author Francis-ChinaFeng
 * @version 1.0 2014-02-14
 */
public class MainActivity extends FragmentActivity {

	private Button mDrawerButton;
	private TextView title;
	private DrawerLayout mDrawerLayout;
	private ListView mDrawerList;

	private String[] menus;
	private List<Fragment> fragments;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        setAdapter();
        setListener();
        if (savedInstanceState == null) {
			selectItem(0);
		}
    }

	private void init() {
		mDrawerButton = (Button) findViewById(R.id.left);
		title = (TextView) findViewById(R.id.title);
		mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
		mDrawerList = (ListView) findViewById(R.id.drawer_list);

		menus = new String[] {
				"Home", "Mercury", "Venus", "Mars", "About", "Setting"
		};
		fragments = new ArrayList<Fragment>();
		fragments.add(HomeFragment.newInstance("Home"));
		fragments.add(MercuryFragment.newInstance("Mercury"));
		fragments.add(VenusFragment.newInstance("Venus"));
		fragments.add(MarsFragment.newInstance("Mars"));
		fragments.add(AboutFragment.newInstance("About"));
		fragments.add(SettingFragment.newInstance("Setting"));
	}

	private void setAdapter() {
		mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, menus));
	}

	private void setListener() {
		mDrawerButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
					mDrawerLayout.closeDrawer(mDrawerList);
				} else {
					mDrawerLayout.openDrawer(mDrawerList);
				}
			}
		});
		mDrawerList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> adapterView, View v, int position,
					long id) {
				selectItem(position);
			}
		});
	}

	private void selectItem(int position) {
		Fragment fragment = fragments.get(position);
		FragmentManager manager = getSupportFragmentManager();
		manager.beginTransaction().replace(R.id.content_frame, fragment).commit();
		title.setText(menus[position]);
		mDrawerList.setItemChecked(position, true);
		mDrawerLayout.closeDrawer(mDrawerList);
	}
}

HomeFragment.java,幾個Fragment檔案的內容都一樣,實際開發在做處理:
/**
 * 
 * @author Francis-ChinaFeng
 * @version 1.0 2014-2-14
 */
public class HomeFragment extends Fragment {

	public static final String TAG = "content";
	private View view;
	private TextView textView;
	private String content;

	public static HomeFragment newInstance(String content) {
		HomeFragment fragment = new HomeFragment();
		Bundle args = new Bundle();
		args.putString(TAG, content);
		fragment.setArguments(args);
		return fragment;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Bundle bundle = getArguments();
		content = bundle != null ? bundle.getString(TAG) : "";
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		view = inflater.inflate(R.layout.fragment_home, container, false);
		init();
		return view;
	}

	private void init() {
		textView = (TextView) view.findViewById(R.id.textview);
		textView.setText(content);
	}

}

至此,左側選單效果就搞定了,效果還不賴。