標籤:android material design
——接上文。
3.2添加抽屜導航
添加隱藏式瀏覽選單跟Android 5.0之前是一樣的,只是以前我們使用ListView來作為菜單容器,現在我們則使用Material Design風格的RecyclerView。
(14)在你工程的java檔案夾中,建立3個名為activity、adapter、model的包,將MainActivity.java移到activtiy包中,這樣做使得你的代碼可以很好地組織和管理。
(15)開啟位於app模組下的build.gradle檔案並添加如下依賴。添加完依賴之後,點擊Build-->Rebuild Project下載所需要的類庫。
build.gradledependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:22.0.0' compile 'com.android.support:recyclerview-v7:21.0.+'}
(16)在model包裡,建立名為NavDrawerItem.java的類,然後添加以下代碼。這個模型類是一個簡單的POJO(Plain Oridinary Java Object即簡單的java對象)類,它定義了隱藏式瀏覽選單的功能表項目。
NavDrawerItem.javapackage androidhive.info.materialdesign.model; public class NavDrawerItem { private boolean showNotify; private String title; public NavDrawerItem() { } public NavDrawerItem(boolean showNotify, String title) { this.showNotify = showNotify; this.title = title; } public boolean isShowNotify() { return showNotify; } public void setShowNotify(boolean showNotify) { this.showNotify = showNotify; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}
(17)在res-->layout下,建立一個名為nav_drawer_row.xml的檔案並添加如下代碼。這個布局渲染了隱藏式瀏覽選單菜單的每一行,如果你想自訂抽屜功能表項目,你需要修改這個布局檔案。在這個例子中,它僅包含一個TextView。
nav_drawer_row.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="wrap_content" android:clickable="true"> <TextView android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="30dp" android:paddingTop="10dp" android:paddingBottom="10dp" android:textSize="15dp" android:textStyle="bold" /> </RelativeLayout>
(18)下載設定檔表徵圖並將它放入drawable檔案夾,這一步是可選的,但是這個表徵圖會在隱藏式瀏覽選單的頭部用到。
(19)建立另一個名為fragment_navigation_drawer.xml的布局檔案並添加如下代碼。這個布局檔案渲染了整個隱藏式瀏覽選單的視圖,這個布局包括一個顯示個人資訊的頭部和一個顯示列表的RecycleView。
fragment_navigation_drawer.xml<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white"> <RelativeLayout android:id="@+id/nav_header_container" android:layout_width="match_parent" android:layout_height="140dp" android:layout_alignParentTop="true" android:background="@color/colorPrimary"> <ImageView android:layout_width="70dp" android:layout_height="70dp" android:src="@drawable/ic_profile" android:scaleType="fitCenter" android:layout_centerInParent="true" /> </RelativeLayout> <android.support.v7.widget.RecyclerView android:id="@+id/drawerList" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/nav_header_container" android:layout_marginTop="15dp" /> </RelativeLayout>
(20)因為RecycleView是自訂的,我們還需要一個adapter來渲染自訂的xml布局,所以在adapter包下面,建立一個名為NavgationDrawerAdapter.java的類並添加如下代碼。這個適配器類inflate了nav_drawer_row.xml並渲染了RecycleView抽屜菜單。
import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView; import java.util.Collections;import java.util.List; /** * Created by Ravi Tamada on 12-03-2015. */public class NavigationDrawerAdapter extends RecyclerView.Adapter<NavigationDrawerAdapter.MyViewHolder> { List<NavDrawerItem> data = Collections.emptyList(); private LayoutInflater inflater; private Context context; public NavigationDrawerAdapter(Context context, List<NavDrawerItem> data) { this.context = context; inflater = LayoutInflater.from(context); this.data = data; } public void delete(int position) { data.remove(position); notifyItemRemoved(position); } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.nav_drawer_row, parent, false); MyViewHolder holder = new MyViewHolder(view); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { NavDrawerItem current = data.get(position); holder.title.setText(current.getTitle()); } @Override public int getItemCount() { return data.size(); } class MyViewHolder extends RecyclerView.ViewHolder { TextView title; public MyViewHolder(View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.title); } }}(21)在activity包下,建立一個名為FragmentDrawer.java的Fragment。在Android Studio裡面,按以下操作來建立一個新的Fragment,在activity包上右鍵-->New-->Fragment-->Fragment(Blank),然後給Fragment命名。
FragmentDrawer.javaimport android.content.Context;import android.content.res.TypedArray;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.widget.DrawerLayout;import android.support.v7.app.ActionBarDrawerToggle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.Toolbar;import android.view.GestureDetector;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.TextView; import java.util.ArrayList;import java.util.List; public class FragmentDrawer extends Fragment { private static String TAG = FragmentDrawer.class.getSimpleName(); private RecyclerView recyclerView; private ActionBarDrawerToggle mDrawerToggle; private DrawerLayout mDrawerLayout; private NavigationDrawerAdapter adapter; private View containerView; private static String[] titles = null; private FragmentDrawerListener drawerListener; public FragmentDrawer() { } public void setDrawerListener(FragmentDrawerListener listener) { this.drawerListener = listener; } public static List<NavDrawerItem> getData() { List<NavDrawerItem> data = new ArrayList<>(); // preparing navigation drawer items for (int i = 0; i < titles.length; i++) { NavDrawerItem navItem = new NavDrawerItem(); navItem.setTitle(titles[i]); data.add(navItem); } return data; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // drawer labels titles = getActivity().getResources().getStringArray(R.array.nav_drawer_labels); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflating view layout View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false); recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList); adapter = new NavigationDrawerAdapter(getActivity(), getData()); recyclerView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() { @Override public void onClick(View view, int position) { drawerListener.onDrawerItemSelected(view, position); mDrawerLayout.closeDrawer(containerView); } @Override public void onLongClick(View view, int position) { } })); return layout; } public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) { containerView = getActivity().findViewById(fragmentId); mDrawerLayout = drawerLayout; mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) { @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); getActivity().invalidateOptionsMenu(); } @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); getActivity().invalidateOptionsMenu(); } @Override public void onDrawerSlide(View drawerView, float slideOffset) { super.onDrawerSlide(drawerView, slideOffset); toolbar.setAlpha(1 - slideOffset / 2); } }; mDrawerLayout.setDrawerListener(mDrawerToggle); mDrawerLayout.post(new Runnable() { @Override public void run() { mDrawerToggle.syncState(); } }); } public static interface ClickListener { public void onClick(View view, int position); public void onLongClick(View view, int position); } static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener { private GestureDetector gestureDetector; private ClickListener clickListener; public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) { this.clickListener = clickListener; gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public void onLongPress(MotionEvent e) { View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null) { clickListener.onLongClick(child, recyclerView.getChildPosition(child)); } } }); } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { View child = rv.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) { clickListener.onClick(child, rv.getChildPosition(child)); } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } } public interface FragmentDrawerListener { public void onDrawerItemSelected(View view, int position); }}(22)最後開啟主Activity的布局檔案(activity_main.xml)並按下面所示來修改布局。在這個布局裡面,我們添加了android.support.v4.widget.DrawerLayout來展示隱藏式瀏覽選單菜單。
當然在<fragment>標籤裡,你需要給出fragmentDrawer正確的路徑。
actiivty_main.xml<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/container_toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <include android:id="@+id/toolbar" layout="@layout/toolbar" /> </LinearLayout> <FrameLayout android:id="@+id/container_body" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> <fragment android:id="@+id/fragment_navigation_drawer" android:name="androidhive.info.materialdesign.activity.FragmentDrawer" android:layout_width="@dimen/nav_drawer_width" android:layout_height="match_parent" android:layout_gravity="start" app:layout="@layout/fragment_navigation_drawer" tools:layout="@layout/fragment_navigation_drawer" /> </android.support.v4.widget.DrawerLayout>
現在所有的布局檔案和java類檔案都準備到位了,讓我們對MainActivity做一些修改來使隱藏式瀏覽選單工作起來。
(23)開啟MainActivity.java檔案並做如下修改。
>實現FragmentDrawer.FragmentDrawerListener介面並添加onDrawerItemSelected()重載。
MainActivity.javaimport android.support.v4.widget.DrawerLayout;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.support.v7.widget.Toolbar;import android.view.Menu;import android.view.MenuItem;import android.view.View; public class MainActivity extends ActionBarActivity implements FragmentDrawer.FragmentDrawerListener { private Toolbar mToolbar; private FragmentDrawer drawerFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mToolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(mToolbar); getSupportActionBar().setDisplayShowHomeEnabled(true); drawerFragment = (FragmentDrawer) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer); drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar); drawerFragment.setDrawerListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @Override public void onDrawerItemSelected(View view, int position) { }}現在如果你運行App,可以看到隱藏式瀏覽選單,在裡面有一個頭部視圖以及一些清單項目。
由於文章較長,請繼續關註:手把手教你打造一個Material Design風格的App(四)
原文地址:http://www.androidhive.info/2015/04/android-getting-started-with-material-design/
手把手教你打造一個Material Design風格的App(三)