NavigationDrawer详解

原创 2015年11月19日 10:57:47
<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);
    }

    
    //将数据与界面进行绑定的操作
@Override  
    public void onBindViewHolder(ViewHolder holder, final int position) {        	
	holder.mTextView.setText(mDataset[position]);        
	holder.mTextView.setOnClickListener(new View.OnClickListener() {            
	    @Override            
	    public void onClick(View view) {                
		mListener.onClick(view, position);            
	    }        
    	});    
    }    

    @Override    
    public 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());



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Android NavigationDrawer 开发详解-实现侧滑效果

NavigationDrawer 简介NavigationDrawer 是 Google 在 Material Design 中推出的一种侧滑导航栏设计风格。说起来可能很抽象,我们直接来看看 网易云音...

NavigationDrawer 间距修改及延伸

google亲儿子View怎么修改新项目中,使用了NavigationDrawer 控件来做侧边栏。第一次使用NavigationDrawer, 踩坑是必不可少的。下面,来展示 Navigation...

最详细的 NavigationDrawer 开发实践总结

接着来写写Android系统UI新特性,本文是我对最近开发过程中应用 NavigationDrawer 特性的详细总结。本文涉及到的所有代码实现细节,会在文末附上源码地址。有问题欢迎在下方留言讨论 。...

Android开发:最详细的 NavigationDrawer 开发实践总结

Android开发:最详细的 NavigationDrawer 开发实践总结 最详细的 NavigationDrawer 开发实践总结 继前面写的两篇文章之后(有问题欢迎反...

android中NavigationDrawer的使用以及添加drawer切换时的动画效果

最近在开发app的时候需要用到NavigationDrawer,但是在添加动画(汉堡图标和箭头图标互转)效果的时候老是出现问题,折腾了好几个小时终于搞定。在这里跟大家分享一下。说明下,我开发时候用的m...

NavigationDrawer抽屉导航栏(如知乎)简析

1.NavigationDrawer抽屉导航栏特点说明 1.这个例子说明了安卓底库自带的DrawerLayout布局控件的一般用法 2.当一个左侧drawer式的导航栏存在时,活动的activity会...

右侧NavigationDrawer

  • 2015-03-18 15:02
  • 2.29MB
  • 下载

NavigationDrawer-colorful.tar

  • 2014-02-28 11:07
  • 2.32MB
  • 下载

NavigationDrawer+Fragment实现侧滑菜单效果

学习了NavigationDrawer 官方Support包中的SlidingMenu版本,练了下手.用到了ListView中item不同的布局 以后会升级加上ViewPager和GridView实...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)