仿知乎程序(一)DrawerLayout与Toolbar

来源:互联网 发布:linux ftp服务 编辑:程序博客网 时间:2024/06/18 05:41

         知乎是一个我比较喜欢的app,里面的内容也很好。因为自己在学习Android,所以就想仿一下,看一下自己能不能实现。做了半个月,大体上实现了一下其中的功能,下面是简单的操作,(不要注意细节 - -|||)

     是不是已经很像了。里面的数据是调用远程数据库中的数据,没有在手机中使用本地数据库。做程序累所以找了一些不让自己累的数据。哇哈哈。。。。。。
     下面我就一步一步的把我做的每一个过程记录下来,算是对学习 android的一个笔记吧。
    这里使用了android 5.0的一些控件,所以SDK我升级到了22。也许有人会说,这样是不是有一些低版本的手机就使用不了呢,这些新的控件官方说明是兼容到2.1。所以我感觉这个应该不是问题。
    好了,我们先把一进来的首页架起来。这里面使用了Toolbar控件,DrawerLayout控件。
    为什么使用toolbar而不使用 actionBar 呢。这里面有两个原因,一是google说toolbar是取代actionbar的,而且比 actionbar更灵活。另一个,看到左上角哪个可动的图标了吗,用toolbar可以直接就实现了,不用第三方插件了。
    DrawerLayout的使用,主要是为了,可以从左侧拉出菜单来。
    下面我就一步一步的把这个实现出来。
    先来看一下activity_main.xml文件:

   

[html] view plain copy
  1. <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:id="@+id/drawer_main"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <LinearLayout  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="match_parent"  
  9.         android:orientation="vertical">  
  10.           
  11.         <!--toolbar菜单-->  
  12.         <include  
  13.             layout="@layout/toolbar" />  
  14.   
  15.   
  16.         <!-- 内容界面 -->  
  17.   
  18.         <FrameLayout  
  19.             android:id="@+id/frame_main"  
  20.             android:layout_width="match_parent"  
  21.             android:layout_height="match_parent" />  
  22.   
  23.     </LinearLayout>  
  24.       
  25.     <!-- 侧滑菜单内容 -->  
  26.   
  27.     <fragment  
  28.         android:id="@+id/navigation_drawer"  
  29.         android:name="com.example.cg.zhihu_one.tool_NavigationDrawerFragment"  
  30.         android:layout_width="240dp"  
  31.         android:layout_height="match_parent"  
  32.         android:layout_gravity="start" />  
  33.   
  34. </android.support.v4.widget.DrawerLayout>  

知识点:
   1,android.support.v4.widget.DrawerLayout:这个是google官方的侧滑菜单控件,它内部分为两个部分,一个是内容部分,另一个侧滑菜单内容。使用很简单,也很方便。但是它有一个问题,说是问题,只是与以前我们自己写的侧滑菜单不同的地方,就是它在侧滑的时候,你的手要放到很靠近手机边的地方,而不是说,在手机屏的正中间,你滑一下,它也会显示侧滑,这种设计,个人感觉还是不错的,因为它可以很好的,就把内部再有滑动的效果给区分开了,我们在里面加一个viewpager,你在侧滑的时候,就会造成想切换viewpager的时候,没切成,反而显示了侧滑菜单。
      这里我把DrawerLayout做为根控件来使用,是因为我要让侧滑菜单,在滑出来的时候,高度是手机屏幕的高,如果你看DrawerLayout的官方文档,你会发现,它侧滑出来的,是在toolbar下面。这是因为它在Drawerlayout外层还有一个根布局。
     注:对于DrawerLayout,其实它是可以左右都有滑出功能的,这一点大家要注意,因为我们这个系统只有一个左侧滑,所以我就用了一个。如果感兴趣,可以试一下,再加一个fragment在下面,但是要注意一点,android:layout_gravity这个值,是用来提供是左滑还是右滑的,里面的值是left|start就是左侧出,right|end就是右侧出。
  2,toolbar: 因为后面还要有页使用,所以为了方便,就做成一个文件,然后include调用了。代码如下:
[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     android:id="@+id/toolbar"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="wrap_content"  
  7.     android:background="?attr/colorPrimary"  
  8.     android:minHeight="?attr/actionBarSize"  
  9.     app:popupTheme="@style/ThemeOverlay.AppCompat.Light"  
  10.     app:theme="@style/ThemeOverlay.AppCompat.ActionBar">  
  11.   
  12. </android.support.v7.widget.Toolbar>  

这里要说明的,就是我们要在style.css文件中为toolbar设置相应的样式。代码如下:
[html] view plain copy
  1. <resources>  
  2.   
  3.     <style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">  
  4.   
  5.         <!-- toolbar(actionbar)颜色 -->  
  6.         <item name="colorPrimary">@color/titleBlue</item>  
  7.         <!-- 状态栏颜色 -->  
  8.         <item name="colorPrimaryDark">#3A5FCD</item>  
  9.         <!--toolbar文字的颜色-->  
  10.         <item name="@android:textColorPrimary">@android:color/white</item>  
  11.         <!-- 窗口的背景颜色 -->  
  12.         <item name="android:windowBackground">@android:color/white</item>  
  13.   
  14.         <!--toolbar上菜单文字的颜色-->  
  15.         <item name="actionMenuTextColor">#ffffff</item>  
  16.   
  17.     </style>  
  18. </resources>  

样式加完,我们在AndroidManifest.xml中添加此样式

[html] view plain copy
  1. <application  
  2.         android:allowBackup="true"  
  3.         android:icon="@mipmap/ic_launcher"  
  4.         android:label="@string/app_name"  
  5.         android:theme="@style/AppBaseTheme" >  
我们再来看一下,侧滑菜单的布局与代码。这里说一句啊。正常这个侧滑布局我们应该使用android.support.design.widget.NavigationView,它是google给我们提供的一个官方控件,非常的好用,使用也简单,但是它有几个问题,我一直没有解决,一是,菜单上的图标,不管你用什么色的,显示全是灰的。二是如果你加了<item android:title="Sub items">,它会在一直显示这个title,如果你把这个title去掉,它是不显示这个文字了,可是相应的位置还是被留了出来,空了好大一块,所以这里只好自己去写一个布局。
fragment_main_drawer.xml
[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical"  
  7.     android:background="#ffffff">  
  8.   
  9.     <LinearLayout  
  10.         android:layout_width="fill_parent"  
  11.         android:layout_height="0dp"  
  12.         android:layout_weight="2"  
  13.         android:orientation="vertical"  
  14.         android:background="#3A5FCD">  
  15.   
  16.         <LinearLayout  
  17.             android:layout_width="fill_parent"  
  18.             android:layout_height="0dp"  
  19.             android:layout_weight="3">  
  20.             <com.example.cg.zhihu_one.untils.CircleImageView  
  21.                 android:layout_width="50dp"  
  22.                 android:layout_height="50dp"  
  23.                 android:layout_margin="10dp"  
  24.                 android:src="@drawable/img_empty_followers"  
  25.                 app:border_width="1dp"  
  26.                 app:border_color="@color/white"  
  27.                 ></com.example.cg.zhihu_one.untils.CircleImageView>  
  28.         </LinearLayout>  
  29.         <TextView  
  30.             android:id="@+id/txt_main_drawer_UserNick"  
  31.             android:layout_width="fill_parent"  
  32.             android:layout_height="0dp"  
  33.             android:layout_weight="1"  
  34.             android:text="我本无名"  
  35.             android:textColor="#ffffff"  
  36.             android:layout_marginTop="10dp"  
  37.             android:layout_marginLeft="10dp"/>  
  38.         <TextView  
  39.             android:id="@+id/txt_main_drawer_UserProfile"  
  40.             android:layout_width="fill_parent"  
  41.             android:layout_height="0dp"  
  42.             android:layout_weight="1"  
  43.             android:text="码农"  
  44.             android:textSize="@dimen/main_drawer_small"  
  45.             android:textColor="#ffffff"  
  46.             android:layout_marginTop="5dp"  
  47.             android:layout_marginLeft="10dp"/>  
  48.   
  49.     </LinearLayout>  
  50.     <ListView  
  51.         android:id="@+id/lv_main_drawer_leftmenu"  
  52.         android:layout_width="fill_parent"  
  53.         android:layout_height="0dp"  
  54.         android:layout_weight="6"  
  55.         android:background="#fff"  
  56.         android:choiceMode="singleChoice"  
  57.         android:layout_marginTop="5dp"  
  58.         android:divider="@null"  
  59.         android:scrollbars="none"></ListView>  
  60.   
  61.     <LinearLayout  
  62.         android:layout_width="fill_parent"  
  63.         android:layout_height="0dp"  
  64.         android:layout_weight="2"  
  65.         android:background="#fff"  
  66.         android:layout_marginTop="5dp"  
  67.         android:orientation="vertical">  
  68.   
  69.         <LinearLayout  
  70.             android:layout_width="fill_parent"  
  71.             android:layout_height="0dp"  
  72.             android:layout_weight="1">  
  73.             <ImageView  
  74.                 android:layout_width="fill_parent"  
  75.                 android:layout_height="1dp"  
  76.                 android:background="@color/grey"/>  
  77.         </LinearLayout>  
  78.   
  79.         <LinearLayout  
  80.             android:layout_width="fill_parent"  
  81.             android:layout_height="0dp"  
  82.             android:layout_weight="4"  
  83.             android:background="@drawable/main_drawer_background"  
  84.             android:clickable="true"  
  85.             android:gravity="center_vertical">  
  86.             <TextView  
  87.                 android:layout_width="fill_parent"  
  88.                 android:layout_height="wrap_content"  
  89.                 android:layout_marginLeft="16dp"  
  90.                 android:text="切换主题"  
  91.                 android:textAppearance="?android:attr/textAppearanceListItemSmall"  
  92.                 android:textColor="@drawable/main_drawer_text_color"  
  93.                 />  
  94.   
  95.         </LinearLayout>  
  96.         <LinearLayout  
  97.             android:layout_width="fill_parent"  
  98.             android:layout_height="0dp"  
  99.             android:layout_weight="4"  
  100.             android:background="@drawable/main_drawer_background"  
  101.             android:clickable="true"  
  102.             android:gravity="center_vertical">  
  103.             <TextView  
  104.                 android:layout_width="fill_parent"  
  105.                 android:layout_height="wrap_content"  
  106.                 android:layout_marginLeft="16dp"  
  107.                 android:text="设置"  
  108.                 android:textAppearance="?android:attr/textAppearanceListItemSmall"  
  109.                 android:textColor="@drawable/main_drawer_text_color"/>  
  110.         </LinearLayout>  
  111.         <LinearLayout  
  112.             android:layout_width="fill_parent"  
  113.             android:layout_height="0dp"  
  114.             android:layout_weight="1"></LinearLayout>  
  115.   
  116.     </LinearLayout>  
  117.   
  118. </LinearLayout>  

知识点:
 1,圆形图:这个不多说,网上有很多现成的例子,这里我把代码复制一下
CircleImageView.java
[java] view plain copy
  1. import android.content.Context;  
  2. import android.content.res.TypedArray;  
  3. import android.graphics.Bitmap;  
  4. import android.graphics.BitmapShader;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Color;  
  7. import android.graphics.ColorFilter;  
  8. import android.graphics.Matrix;  
  9. import android.graphics.Paint;  
  10. import android.graphics.RectF;  
  11. import android.graphics.Shader;  
  12. import android.graphics.drawable.BitmapDrawable;  
  13. import android.graphics.drawable.ColorDrawable;  
  14. import android.graphics.drawable.Drawable;  
  15. import android.net.Uri;  
  16. import android.support.annotation.ColorRes;  
  17. import android.support.annotation.DrawableRes;  
  18. import android.util.AttributeSet;  
  19. import android.widget.ImageView;  
  20.   
  21. import com.example.cg.zhihu_one.R;  
  22.   
  23.   
  24. /** 
  25.  * Created by cg on 2015/8/26. 
  26.  */  
  27. public class CircleImageView extends ImageView {  
  28.     private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;  
  29.   
  30.     private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;  
  31.     private static final int COLORDRAWABLE_DIMENSION = 2;  
  32.   
  33.     private static final int DEFAULT_BORDER_WIDTH = 0;  
  34.     private static final int DEFAULT_BORDER_COLOR = Color.BLACK;  
  35.     private static final boolean DEFAULT_BORDER_OVERLAY = false;  
  36.   
  37.     private final RectF mDrawableRect = new RectF();  
  38.     private final RectF mBorderRect = new RectF();  
  39.   
  40.     private final Matrix mShaderMatrix = new Matrix();  
  41.     private final Paint mBitmapPaint = new Paint();  
  42.     private final Paint mBorderPaint = new Paint();  
  43.   
  44.     private int mBorderColor = DEFAULT_BORDER_COLOR;  
  45.     private int mBorderWidth = DEFAULT_BORDER_WIDTH;  
  46.   
  47.     private Bitmap mBitmap;  
  48.     private BitmapShader mBitmapShader;  
  49.     private int mBitmapWidth;  
  50.     private int mBitmapHeight;  
  51.   
  52.     private float mDrawableRadius;  
  53.     private float mBorderRadius;  
  54.   
  55.     private ColorFilter mColorFilter;  
  56.   
  57.     private boolean mReady;  
  58.     private boolean mSetupPending;  
  59.     private boolean mBorderOverlay;  
  60.   
  61.     public CircleImageView(Context context) {  
  62.         super(context);  
  63.   
  64.         init();  
  65.     }  
  66.   
  67.     public CircleImageView(Context context, AttributeSet attrs) {  
  68.         this(context, attrs, 0);  
  69.     }  
  70.   
  71.     public CircleImageView(Context context, AttributeSet attrs, int defStyle) {  
  72.         super(context, attrs, defStyle);  
  73.   
  74.         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);  
  75.   
  76.         mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);  
  77.         mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);  
  78.         mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_border_overlay, DEFAULT_BORDER_OVERLAY);  
  79.   
  80.         a.recycle();  
  81.   
  82.         init();  
  83.     }  
  84.   
  85.     private void init() {  
  86.         super.setScaleType(SCALE_TYPE);  
  87.         mReady = true;  
  88.   
  89.         if (mSetupPending) {  
  90.             setup();  
  91.             mSetupPending = false;  
  92.         }  
  93.     }  
  94.   
  95.     @Override  
  96.     public ScaleType getScaleType() {  
  97.         return SCALE_TYPE;  
  98.     }  
  99.   
  100.     @Override  
  101.     public void setScaleType(ScaleType scaleType) {  
  102.         if (scaleType != SCALE_TYPE) {  
  103.             throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));  
  104.         }  
  105.     }  
  106.   
  107.     @Override  
  108.     public void setAdjustViewBounds(boolean adjustViewBounds) {  
  109.         if (adjustViewBounds) {  
  110.             throw new IllegalArgumentException("adjustViewBounds not supported.");  
  111.         }  
  112.     }  
  113.   
  114.     @Override  
  115.     protected void onDraw(Canvas canvas) {  
  116.         if (getDrawable() == null) {  
  117.             return;  
  118.         }  
  119.   
  120.         canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);  
  121.         if (mBorderWidth != 0) {  
  122.             canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);  
  123.         }  
  124.     }  
  125.   
  126.     @Override  
  127.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  128.         super.onSizeChanged(w, h, oldw, oldh);  
  129.         setup();  
  130.     }  
  131.   
  132.     public int getBorderColor() {  
  133.         return mBorderColor;  
  134.     }  
  135.   
  136.     public void setBorderColor(int borderColor) {  
  137.         if (borderColor == mBorderColor) {  
  138.             return;  
  139.         }  
  140.   
  141.         mBorderColor = borderColor;  
  142.         mBorderPaint.setColor(mBorderColor);  
  143.         invalidate();  
  144.     }  
  145.   
  146.     public void setBorderColorResource(@ColorRes int borderColorRes) {  
  147.         setBorderColor(getContext().getResources().getColor(borderColorRes));  
  148.     }  
  149.   
  150.     public int getBorderWidth() {  
  151.         return mBorderWidth;  
  152.     }  
  153.   
  154.     public void setBorderWidth(int borderWidth) {  
  155.         if (borderWidth == mBorderWidth) {  
  156.             return;  
  157.         }  
  158.   
  159.         mBorderWidth = borderWidth;  
  160.         setup();  
  161.     }  
  162.   
  163.     public boolean isBorderOverlay() {  
  164.         return mBorderOverlay;  
  165.     }  
  166.   
  167.     public void setBorderOverlay(boolean borderOverlay) {  
  168.         if (borderOverlay == mBorderOverlay) {  
  169.             return;  
  170.         }  
  171.   
  172.         mBorderOverlay = borderOverlay;  
  173.         setup();  
  174.     }  
  175.   
  176.     @Override  
  177.     public void setImageBitmap(Bitmap bm) {  
  178.         super.setImageBitmap(bm);  
  179.         mBitmap = bm;  
  180.         setup();  
  181.     }  
  182.   
  183.     @Override  
  184.     public void setImageDrawable(Drawable drawable) {  
  185.         super.setImageDrawable(drawable);  
  186.         mBitmap = getBitmapFromDrawable(drawable);  
  187.         setup();  
  188.     }  
  189.   
  190.     @Override  
  191.     public void setImageResource(@DrawableRes int resId) {  
  192.         super.setImageResource(resId);  
  193.         mBitmap = getBitmapFromDrawable(getDrawable());  
  194.         setup();  
  195.     }  
  196.   
  197.     @Override  
  198.     public void setImageURI(Uri uri) {  
  199.         super.setImageURI(uri);  
  200.         mBitmap = getBitmapFromDrawable(getDrawable());  
  201.         setup();  
  202.     }  
  203.   
  204.     @Override  
  205.     public void setColorFilter(ColorFilter cf) {  
  206.         if (cf == mColorFilter) {  
  207.             return;  
  208.         }  
  209.   
  210.         mColorFilter = cf;  
  211.         mBitmapPaint.setColorFilter(mColorFilter);  
  212.         invalidate();  
  213.     }  
  214.   
  215.     private Bitmap getBitmapFromDrawable(Drawable drawable) {  
  216.         if (drawable == null) {  
  217.             return null;  
  218.         }  
  219.   
  220.         if (drawable instanceof BitmapDrawable) {  
  221.             return ((BitmapDrawable) drawable).getBitmap();  
  222.         }  
  223.   
  224.         try {  
  225.             Bitmap bitmap;  
  226.   
  227.             if (drawable instanceof ColorDrawable) {  
  228.                 bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);  
  229.             } else {  
  230.                 bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);  
  231.             }  
  232.   
  233.             Canvas canvas = new Canvas(bitmap);  
  234.             drawable.setBounds(00, canvas.getWidth(), canvas.getHeight());  
  235.             drawable.draw(canvas);  
  236.             return bitmap;  
  237.         } catch (OutOfMemoryError e) {  
  238.             return null;  
  239.         }  
  240.     }  
  241.   
  242.     private void setup() {  
  243.         if (!mReady) {  
  244.             mSetupPending = true;  
  245.             return;  
  246.         }  
  247.   
  248.         if (mBitmap == null) {  
  249.             return;  
  250.         }  
  251.   
  252.         mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);  
  253.   
  254.         mBitmapPaint.setAntiAlias(true);  
  255.         mBitmapPaint.setShader(mBitmapShader);  
  256.   
  257.         mBorderPaint.setStyle(Paint.Style.STROKE);  
  258.         mBorderPaint.setAntiAlias(true);  
  259.         mBorderPaint.setColor(mBorderColor);  
  260.         mBorderPaint.setStrokeWidth(mBorderWidth);  
  261.   
  262.         mBitmapHeight = mBitmap.getHeight();  
  263.         mBitmapWidth = mBitmap.getWidth();  
  264.   
  265.         mBorderRect.set(00, getWidth(), getHeight());  
  266.         mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);  
  267.   
  268.         mDrawableRect.set(mBorderRect);  
  269.         if (!mBorderOverlay) {  
  270.             mDrawableRect.inset(mBorderWidth, mBorderWidth);  
  271.         }  
  272.         mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);  
  273.   
  274.         updateShaderMatrix();  
  275.         invalidate();  
  276.     }  
  277.   
  278.     private void updateShaderMatrix() {  
  279.         float scale;  
  280.         float dx = 0;  
  281.         float dy = 0;  
  282.   
  283.         mShaderMatrix.set(null);  
  284.   
  285.         if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {  
  286.             scale = mDrawableRect.height() / (float) mBitmapHeight;  
  287.             dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;  
  288.         } else {  
  289.             scale = mDrawableRect.width() / (float) mBitmapWidth;  
  290.             dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;  
  291.         }  
  292.   
  293.         mShaderMatrix.setScale(scale, scale);  
  294.         mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);  
  295.   
  296.         mBitmapShader.setLocalMatrix(mShaderMatrix);  
  297.     }  
  298. }  

控件中自定义了几个属性,在values文件夹里,建attrs.xml文件文件,代码如下:
[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <declare-styleable name="CircleImageView">  
  4.         <attr name="border_width" format="dimension" />  
  5.         <attr name="border_color" format="color" />  
  6.         <attr name="border_overlay" format="boolean" />  
  7.     </declare-styleable>  
  8. </resources>  

2,菜单使用listView,代码如下:
   listview中的item页面代码:

fragment_main_drawer_item.xml

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:padding="16dp"  
  6.     android:gravity="center_vertical"  
  7.     android:background="@drawable/main_drawer_background"  
  8.     android:orientation="horizontal">  
  9.   
  10.     <ImageView  
  11.         android:id="@+id/item_icon"  
  12.         android:layout_marginRight="10dp"  
  13.         android:layout_width="wrap_content"  
  14.         android:layout_height="wrap_content"/>  
  15.   
  16.     <TextView  
  17.         android:id="@+id/item_title"  
  18.         android:layout_width="wrap_content"  
  19.         android:layout_height="wrap_content"  
  20.         android:textAppearance="?android:attr/textAppearanceListItemSmall"  
  21.         android:textColor="@drawable/main_drawer_text_color"  
  22.         android:gravity="center_vertical"  
  23.         />  
  24.   
  25. </LinearLayout>  

这里面的android:background="@drawable/main_drawer_background"主要是在点击菜单时,改变背景色
main_drawer_background.xml
[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item  
  4.         android:state_activated="true"  
  5.         android:drawable="@color/grey" />  
  6.     <item  
  7.         android:state_focused="false"  
  8.         android:state_pressed="true"  
  9.         android:drawable="@color/grey" />  
  10.     <item android:drawable="@android:color/transparent" />  
  11. </selector>  

main_drawer_text_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_enabled="false"
        android:color="#ff999999"/>
    <item
        android:state_activated="true"
        android:color="@android:color/white" />
    <item
        android:color="#636363" />
</selector>
现在item已经有了,哪么我们就为这个菜单列表写一个adapter
Main_Drawer_lv_Adapter.java
[java] view plain copy
  1. import android.content.Context;  
  2. import android.view.LayoutInflater;  
  3. import android.view.View;  
  4. import android.view.ViewGroup;  
  5. import android.widget.BaseAdapter;  
  6. import android.widget.ImageView;  
  7. import android.widget.TextView;  
  8.   
  9. import com.example.cg.zhihu_one.R;  
  10. import com.example.cg.zhihu_one.models.MainDrawerMenu;  
  11.   
  12. import java.util.List;  
  13.   
  14. /** 
  15.  * 左侧侧滑菜单的adpter 
  16.  * Created by cg on 2015/10/26. 
  17.  */  
  18. public class Main_Drawer_lv_Adapter extends BaseAdapter {  
  19.     private LayoutInflater inflater;  
  20.     private List<MainDrawerMenu> list_menu;                   //菜单名称与图标的list,采用了一个类  
  21.   
  22.     public Main_Drawer_lv_Adapter(Context context,List<MainDrawerMenu> list_menu) {  
  23.         inflater = LayoutInflater.from(context);  
  24.         this.list_menu = list_menu;  
  25.     }  
  26.   
  27.     @Override  
  28.     public int getCount() {  
  29.         return list_menu.size();  
  30.     }  
  31.   
  32.     @Override  
  33.     public Object getItem(int position) {  
  34.         return list_menu.get(position);  
  35.     }  
  36.   
  37.     @Override  
  38.     public long getItemId(int position) {  
  39.         return position;  
  40.     }  
  41.   
  42.     @Override  
  43.     public View getView(int position, View convertView, ViewGroup parent) {  
  44.   
  45.         menuItem mItem;  
  46.         if(convertView==null)  
  47.         {  
  48.             convertView = inflater.inflate(R.layout.fragment_main_drawer_item,null);  
  49.             mItem = new menuItem();  
  50.             mItem.icon = (ImageView)convertView.findViewById(R.id.item_icon);  
  51.             mItem.title = (TextView)convertView.findViewById(R.id.item_title);  
  52.             convertView.setTag(mItem);  
  53.         }else{  
  54.             mItem = (menuItem)convertView.getTag();  
  55.         }  
  56.   
  57.         mItem.icon.setImageResource(list_menu.get(position).getMainDrawer_icon());  
  58.         mItem.title.setText(list_menu.get(position).getMainDrawer_menuName());  
  59.   
  60.         return convertView;  
  61.     }  
  62.   
  63.     public class menuItem  
  64.     {  
  65.         ImageView icon;  
  66.         TextView title;  
  67.     }  
  68. }  

这里面为了将图标和文字传入,我建立了一个model类。
MainDrawerMenu.java
[java] view plain copy
  1. /** 
  2.  * 左侧侧滑菜单内容类 
  3.  * Created by cg on 2015/10/23. 
  4.  */  
  5. public class MainDrawerMenu {  
  6.     private int mainDrawer_icon;                      //菜单的图标  
  7.     private String mainDrawer_menuName;               //菜单的名称  
  8.   
  9.     public MainDrawerMenu() {  
  10.     }  
  11.   
  12.     public MainDrawerMenu(int mainDrawer_icon, String mainDrawer_menuName) {  
  13.         this.mainDrawer_icon = mainDrawer_icon;  
  14.         this.mainDrawer_menuName = mainDrawer_menuName;  
  15.     }  
  16.   
  17.     /** 
  18.      * 得到菜单图标 
  19.      * @return 
  20.      */  
  21.     public int getMainDrawer_icon() {  
  22.         return mainDrawer_icon;  
  23.     }  
  24.   
  25.     /** 
  26.      * 设置菜单图标 
  27.      * @param mainDrawer_icon 
  28.      */  
  29.     public void setMainDrawer_icon(int mainDrawer_icon) {  
  30.         this.mainDrawer_icon = mainDrawer_icon;  
  31.     }  
  32.   
  33.     /** 
  34.      * 得到菜单名称 
  35.      * @return 
  36.      */  
  37.     public String getMainDrawer_menuName() {  
  38.         return mainDrawer_menuName;  
  39.     }  
  40.   
  41.     /** 
  42.      * 设置菜单名称 
  43.      * @param mainDrawer_menuName 
  44.      */  
  45.     public void setMainDrawer_menuName(String mainDrawer_menuName) {  
  46.         this.mainDrawer_menuName = mainDrawer_menuName;  
  47.     }  
  48. }  

现在布局有了,圆形图搞定,listview的item布局和adapter也完事了,下面就把这些整合起来吧.
tool_NavigationDrawerFragment.java
[java] view plain copy
  1. import android.app.Fragment;  
  2. import android.content.res.TypedArray;  
  3. import android.os.Bundle;  
  4. import android.view.LayoutInflater;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. import android.widget.AdapterView;  
  8. import android.widget.ListView;  
  9.   
  10. import com.example.cg.zhihu_one.Adapters.Main_Drawer_lv_Adapter;  
  11. import com.example.cg.zhihu_one.models.MainDrawerMenu;  
  12.   
  13. import java.util.ArrayList;  
  14. import java.util.List;  
  15.   
  16. /** 
  17.  * 左侧侧滑页面 
  18.  * Created by cg on 2015/10/23. 
  19.  */  
  20. public class tool_NavigationDrawerFragment extends Fragment {  
  21.     private ListView lv_main_drawer_leftmenu;                                                 //定义菜单的listView  
  22.     private List<MainDrawerMenu> list_menu;  
  23.   
  24.   
  25.     /** 
  26.      *  设置菜单点击接口,以方便外部Activity调用 
  27.      */  
  28.     public interface menuClickListener  
  29.     {  
  30.         void menuClick(String menuName);  
  31.     }  
  32.   
  33.     @Override  
  34.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
  35.   
  36.         View view = inflater.inflate(R.layout.fragment_main_drawer,container,false);  
  37.   
  38.         initleftMenuContral(view);  
  39.   
  40.         return view;  
  41.     }  
  42.   
  43.     /** 
  44.      * 初始化左侧菜单列表listView,并为菜单,设置点击事件 
  45.      * @param view 
  46.      */  
  47.     private void initleftMenuContral(View view) {  
  48.         lv_main_drawer_leftmenu = (ListView)view.findViewById(R.id.lv_main_drawer_leftmenu);  
  49.         list_menu = getMenuItem();  
  50.         lv_main_drawer_leftmenu.setAdapter(new Main_Drawer_lv_Adapter(getActivity(),list_menu));  
  51.         lv_main_drawer_leftmenu.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  52.             @Override  
  53.             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
  54.                 if(getActivity() instanceof menuClickListener)  
  55.                 {  
  56.                     ((menuClickListener)getActivity()).menuClick(list_menu.get(position).getMainDrawer_menuName());  
  57.                 }  
  58.             }  
  59.         });  
  60.     }  
  61.   
  62.     /** 
  63.      * 从arrays.xml中取出数据,装入list<T>中 
  64.      * @return 
  65.      */  
  66.     private List<MainDrawerMenu> getMenuItem()  
  67.     {  
  68.         List<MainDrawerMenu> list_menu = new ArrayList<MainDrawerMenu>();  
  69.   
  70.         String[] itemTitle = getResources().getStringArray(R.array.item_title);  
  71.         TypedArray itemIconRes = getResources().obtainTypedArray(R.array.item_icon_res);  
  72.   
  73.         for(int i=0;i<itemTitle.length;i++)  
  74.         {  
  75.   
  76.             MainDrawerMenu lmi = new MainDrawerMenu();  
  77.             lmi.setMainDrawer_icon(itemIconRes.getResourceId(i,0));  
  78.             lmi.setMainDrawer_menuName(itemTitle[i]);  
  79.             list_menu.add(lmi);  
  80.         }  
  81.   
  82.         return list_menu;  
  83.     }  
  84. }  

这里说明一点,这里的菜单名和图标,我采用的是在values文件夹建立了一个arrays.xml文件,把这些值写在了这里。
[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string-array name="item_title">  
  4.         <item>首页</item>  
  5.         <item>发现</item>  
  6.         <item>关注</item>  
  7.         <item>收藏</item>  
  8.         <item>草稿</item>  
  9.         <item>提问</item>  
  10.     </string-array>  
  11.   
  12.     <integer-array name="item_icon_res">  
  13.         <item>@drawable/ic_drawer_home_normal</item>  
  14.         <item>@drawable/ic_drawer_explore_normal</item>  
  15.         <item>@drawable/ic_drawer_follow_normal</item>  
  16.         <item>@drawable/ic_drawer_collect_normal</item>  
  17.         <item>@drawable/ic_drawer_draft_normal</item>  
  18.         <item>@drawable/ic_drawer_question_normal</item>  
  19.     </integer-array>  
  20. </resources>  

到这里,我们的toolbar,左侧菜单都已经建立完成了,我们来运行一下看一下效果。
左侧菜单没问题,已经实现了我们的想法,可是这个toolbar上面,处了背景色以外,什么都没有,这是什么情况呢,这是因为我们还没有给toolbar进行设置,好了,我们来看一下MainActivity.java的代码.
[java] view plain copy
  1. import android.os.Bundle;  
  2. import android.support.v4.widget.DrawerLayout;  
  3. import android.support.v7.app.ActionBarDrawerToggle;  
  4. import android.support.v7.app.AppCompatActivity;  
  5. import android.support.v7.widget.Toolbar;  
  6. import android.view.Menu;  
  7. import android.view.MenuItem;  
  8.   
  9. public class MainActivity extends AppCompatActivity {  
  10.   
  11.     private Toolbar toolbar;                             //定义toolbar  
  12.     private ActionBarDrawerToggle mDrawerToggle;         //定义toolbar左上角的弹出左侧菜单按钮  
  13.     private DrawerLayout drawer_main;                    //定义左侧滑动布局,其实就是主布局  
  14.   
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_main);  
  19.   
  20.         initToolbar();  
  21.     }  
  22.   
  23.     /** 
  24.      * 初始化Toolbar,并设置Toolbar中的菜单与标题,并与DrawerLayout.DrawerListener相关联,设置动态图标 
  25.      */  
  26.     public void initToolbar()  
  27.     {  
  28.         toolbar = (Toolbar)this.findViewById(R.id.toolbar);  
  29.         toolbar.setTitle("首页");                     // 标题的文字需在setSupportActionBar之前,不然会无效  
  30.         setSupportActionBar(toolbar);  
  31.   
  32.         //为了生成,工具栏左上角的动态图标,要使用下面的方法  
  33.         drawer_main = (DrawerLayout) findViewById(R.id.drawer_main);  
  34.         mDrawerToggle = new ActionBarDrawerToggle(this, drawer_main, toolbar, R.string.drawer_open,  
  35.                 R.string.drawer_close);  
  36.         mDrawerToggle.syncState();  
  37.         drawer_main.setDrawerListener(mDrawerToggle);  
  38.     }  
  39.   
  40.     @Override  
  41.     public boolean onCreateOptionsMenu(Menu menu) {  
  42.         // Inflate the menu; this adds items to the action bar if it is present.  
  43.         getMenuInflater().inflate(R.menu.menu_main, menu);  
  44.         return true;  
  45.     }  
  46.   
  47.     @Override  
  48.     public boolean onOptionsItemSelected(MenuItem item) {  
  49.         // Handle action bar item clicks here. The action bar will  
  50.         // automatically handle clicks on the Home/Up button, so long  
  51.         // as you specify a parent activity in AndroidManifest.xml.  
  52.         int id = item.getItemId();  
  53.   
  54.         //noinspection SimplifiableIfStatement  
  55.         if (id == R.id. main_toolbar_shuffle) {  
  56.             return true;  
  57.         }  
  58.   
  59.         return super.onOptionsItemSelected(item);  
  60.     }  
  61. }  

这里,我们还要在menu_main.xml中设置在toolbar上的菜单,代码如下:
[html] view plain copy
  1. <menu xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  3.     xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">  
  4.   
  5.     <item  
  6.         android:id="@+id/main_toolbar_shuffle"  
  7.         android:title="@string/menu_shuffle"  
  8.         android:icon="@drawable/ic_action_shuffle"  
  9.         app:showAsAction="always" />  
  10.     <item  
  11.         android:id="@+id/main_toolbar_search"  
  12.         android:title="@string/menu_search"  
  13.         android:icon="@drawable/ic_action_search"  
  14.         app:showAsAction="always"/>  
  15.     <item  
  16.         android:id="@+id/main_toolbar_notify"  
  17.         android:title="@string/menu_notify"  
  18.         android:icon="@drawable/ic_action_notify"  
  19.         app:showAsAction="always" />  
  20.   
  21.     <item  
  22.         android:id="@+id/main_toolbar_about"  
  23.         android:title="@string/menu_about"  
  24.         app:showAsAction="never" />  
  25.     <item  
  26.         android:id="@+id/main_toolbar_register"  
  27.         android:title="@string/menu_register"  
  28.         app:showAsAction="never" />  
  29. </menu>  

为了方便我们修改菜单名和可以重复使用,我们把文字放到了strings.xml中
[html] view plain copy
  1. <string name="menu_index">首页</string>  
  2.     <string name="menu_search">查询</string>  
  3.     <string name="menu_notify">通知</string>  
  4.     <string name="menu_about">关于</string>  
  5.     <string name="menu_register">登出</string>  
  6.     <string name="menu_share">分享</string>  
  7.     <string name="menu_shuffle">随机看</string>  

好了,这回我们再运行一下,看一下效果:


下载地址:http://download.csdn.net/detail/chenguang79/9215873

转自:http://blog.csdn.net/chenguang79/article/details/49444787


0 0