<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView style="@style/Widget.SampleMessage" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/horizontal_page_margin" android:layout_marginRight="@dimen/horizontal_page_margin" android:layout_marginTop="@dimen/vertical_page_margin" android:layout_marginBottom="@dimen/vertical_page_margin" android:text="@string/intro_message" /> <GridView android:id="@android:id/list" style="@style/Widget.SampleDashboard.Grid" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:paddingLeft="@dimen/horizontal_page_margin" android:paddingRight="@dimen/horizontal_page_margin" android:paddingBottom="@dimen/vertical_page_margin" android:scrollbarStyle="outsideOverlay" /> </LinearLayout>
public class MainActivity extends Activity implements AdapterView.OnItemClickListener { private Sample[] mSamples; private GridView mGridView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Prepare list of samples in this dashboard. mSamples = new Sample[]{ new Sample(R.string.navigationdraweractivity_title, R.string.navigationdraweractivity_description, NavigationDrawerActivity.class), }; // Prepare the GridView mGridView = (GridView) findViewById(android.R.id.list); mGridView.setAdapter(new SampleAdapter()); mGridView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> container, View view, int position, long id) { startActivity(mSamples[position].intent); } private class SampleAdapter extends BaseAdapter { @Override public int getCount() { return mSamples.length; } @Override public Object getItem(int position) { return mSamples[position]; } @Override public long getItemId(int position) { return mSamples[position].hashCode(); } @Override public View getView(int position, View convertView, ViewGroup container) { if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.sample_dashboard_item, container, false); } ((TextView) convertView.findViewById(android.R.id.text1)).setText( mSamples[position].titleResId); ((TextView) convertView.findViewById(android.R.id.text2)).setText( mSamples[position].descriptionResId); return convertView; } } private class Sample { int titleResId; int descriptionResId; Intent intent; private Sample(int titleResId, int descriptionResId, Intent intent) { this.intent = intent; this.titleResId = titleResId; this.descriptionResId = descriptionResId; } private Sample(int titleResId, int descriptionResId, Class<? extends Activity> activityClass) { this(titleResId, descriptionResId, new Intent(MainActivity.this, activityClass)); } } }<?xml version="1.0" encoding="utf-8"?><!-- Copyright 2014 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. --> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:openDrawer="start"> <!-- As the main content view, the view below consumes the entire space available using match_parent in both dimensions. --> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- android:layout_gravity="start" tells DrawerLayout to treat this as a sliding drawer on the left side for left-to-right languages and on the right side for right-to-left languages. The drawer is given a fixed width in dp and extends the full height of the container. A solid background is used for contrast with the content view. --> <android.support.v7.widget.RecyclerView android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="left|start" android:choiceMode="singleChoice" android:divider="@null" android:scrollbars="vertical" /> </android.support.v4.widget.DrawerLayout>
public class NavigationDrawerActivity extends Activity implements PlanetAdapter.OnItemClickListener {//抽屉菜单布局 private DrawerLayout mDrawerLayout; private RecyclerView mDrawerList;//抽屉切换的Actionbar 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_navigation_drawer); mTitle = mDrawerTitle = getTitle(); mPlanetTitles = getResources().getStringArray(R.array.planets_array); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (RecyclerView) findViewById(R.id.left_drawer); // set a custom shadow that overlays the main content when the drawer opens//设置自定义的阴影当抽屉菜单打开的时候可以覆盖在主内容上 mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); // improve performance by indicating the list if fixed size.//设置RecycleView的布局管理器,来确定每一个Item的排列方式
//如果要使用横向布局可以改成myLinearLayout.setOrientation(LinearLayoutManager.HORIZONTAL)LinearLayoutManager myLinearLayout = new LinearLayoutManager(this);mDrawerList.setLayoutManager(myLinearLayout); //adapter的改变不会影响RecycleView的大小就设置成true,换句话说就是如果可以确定每个//item的高度是固定的,设置这个选项可以提高性能 mDrawerList.setHasFixedSize(true); // set up the drawer's list view with items and click listener//抽屉菜单的点击事件需要我们自己写回调去实现,实现回调的一个好地方就是Adapter里面 mDrawerList.setAdapter(new PlanetAdapter(mPlanetTitles, this)); // 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//ActionBarDrawerToggle将抽屉菜单和ActionBar的图标联系在一起,实现它们之间的交互 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); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.navigation_drawer, menu); return true; } /* Called whenever we call invalidateOptionsMenu() */ @Override public boolean onPrepareOptionsMenu(Menu menu) { // If the nav drawer is open, hide action items related to the content view//判断抽屉菜单是否打开 boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_websearch).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // The action bar home/up action should open or close the drawer. // ActionBarDrawerToggle will take care of this. if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } // Handle action buttons switch (item.getItemId()) { case R.id.action_websearch: // create intent to perform web search for this planet Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); intent.putExtra(SearchManager.QUERY, getActionBar().getTitle()); // catch event that there's no activity to handle intent//查看本类中是否有应用程序可以执行给定的QUERY操作 if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } else { Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show(); } return true; default: return super.onOptionsItemSelected(item); } } /* The click listener for RecyclerView in the navigation drawer */ @Override public void onClick(View view, int position) { selectItem(position); } private void selectItem(int position) { // update the main content by replacing fragments Fragment fragment = PlanetFragment.newInstance(position); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction ft = fragmentManager.beginTransaction(); ft.replace(R.id.content_frame, fragment); ft.commit(); // update selected item title, then close the drawer setTitle(mPlanetTitles[position]);//关闭抽屉菜单 mDrawerLayout.closeDrawer(mDrawerList); } @Override public void setTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle); } /** * When using the ActionBarDrawerToggle, you must call it during * onPostCreate() and onConfigurationChanged()... * 当activity启动完成的时候调用,在onStart()和onRestoreInstanceState(Bundle)被调用之后调用 */ @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Pass any configuration change to the drawer toggls mDrawerToggle.onConfigurationChanged(newConfig); } /** * Fragment that appears in the "content_frame", shows a planet */ public static class PlanetFragment extends Fragment { public static final String ARG_PLANET_NUMBER = "planet_number"; public PlanetFragment() { // Empty constructor required for fragment subclasses } public static Fragment newInstance(int position) { Fragment fragment = new PlanetFragment(); Bundle args = new Bundle(); args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_planet, container, false); 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 iv = ((ImageView) rootView.findViewById(R.id.image)); iv.setImageResource(imageId); getActivity().setTitle(planet); return rootView; } } }//自定义的Adapter需实现RecyclerView.Adapter
public class PlanetAdapter extends RecyclerView.Adapter<PlanetAdapter.ViewHolder> { private String[] mDataset; private OnItemClickListener mListener; /** * Interface for receiving click events from cells. */ public interface OnItemClickListener { void onClick(View view, int position); } /** * Custom viewholder for our planet views. */ public static class ViewHolder extends RecyclerView.ViewHolder { public final TextView mTextView; public ViewHolder(TextView v) { super(v); mTextView = v; } } public PlanetAdapter(String[] myDataset, OnItemClickListener listener) { mDataset = myDataset; mListener = listener; }//创建新ViewHolder,新的ViewHolder将被onBindViewHolder用于显示Adapter的Item@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater vi = LayoutInflater.from(parent.getContext()); View v = vi.inflate(R.layout.drawer_list_item, parent, false); TextView tv = (TextView) v.findViewById(android.R.id.text1); return new ViewHolder(tv); }//将数据与界面进行绑定的操作
@Overridepublic void onBindViewHolder(ViewHolder holder, final int position) {holder.mTextView.setText(mDataset[position]);holder.mTextView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mListener.onClick(view, position);}
});}
@Overridepublic int getItemCount() {return mDataset.length;}}<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"/>
在RecycleView中添加和删除数据以前在ListView当中,我们只要修改后数据用Adapter的notifyDatasetChange一下就可以更新界面。 然而在RecyclerView中还有一些更高级的用法: 添加数据: public void addItem(DataModel content, int position) { datas.add(position, content); notifyItemInserted(position); //Attention! } 删除数据: public void removeItem(DataModel model) { int position = datas.indexOf(model); datas.remove(position); notifyItemRemoved(position);//Attention! } 值得注意的是RecyclerView的添加删除都是有默认的动画效果的,如果没有效果可以添加如下代码: mRecyclerView.setItemAnimator(new DefaultItemAnimator());