美文网首页
Android 小技巧之 NavigationView

Android 小技巧之 NavigationView

作者: Kevin_小飞象 | 来源:发表于2019-06-12 16:52 被阅读0次

    NavigationView 是一个标准的导航菜单,其菜单内容由菜单资源文件来填充,NavigationView 一般和 DrawerLayout 一起搭配使用构成抽屉菜单,分别由内容页和菜单页组成。

    1. 配置 app/build.gradle

    dependencies {
        implementation 'com.android.support:design:28.0.0'
        implementation 'com.android.support:recyclerview-v7:28.0.0'
        implementation 'com.android.support:cardview-v7:28.0.0'
        implementation 'com.zhy:base-rvadapter:3.0.3'
    }
    

    2. 在 styles.xml 中设置样式

        <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
            <item name="android:actionMenuTextColor">#FFFFFF</item>
        </style>
    
        <style name="nav_size_theme">
            <item name="android:fontFamily">sans-serif</item>
            <item name="android:textSize">14sp</item>
            <item name="android:textStyle">normal</item>
        </style>
    

    3. 布局文件 & 代码

    1)activity_second.xml

    <?xml version="1.0" encoding="utf-8"?>
    <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"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">
    
        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:layout_marginTop="-25dp"
            android:fitsSystemWindows="true"
            android:paddingTop="10dp"
            app:headerLayout="@layout/nav_header_main"
            app:itemBackground="@drawable/nav_item_bg"
            app:itemIconTint="@color/viewDashBoard"
            app:itemTextColor="@color/viewDashBoard"
            app:theme="@style/nav_size_theme"
            app:menu="@menu/activity_main_drawer" />
    </android.support.v4.widget.DrawerLayout>
    

    2)nav_header_main.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="200dp"
        android:background="?attr/colorPrimaryDark"
        android:orientation="vertical"
        android:gravity="center_horizontal"
        android:theme="@style/ThemeOverlay.AppCompat.Dark">
        <com.scarf.xxx.widget.CircleImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginTop="50dp"
            android:src="@drawable/ic_item_img"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Scarf"
            android:textColor="@color/white"  
            android:textSize="20sp"/>
    </LinearLayout>
    

    3)CircleImageView.java

    /**
     * Created on 2019/6/5 10:03 AM
     *
     * @author Scarf Gong
     */
    @SuppressLint("AppCompatCustomView")
    public class CircleImageView extends ImageView {
        private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
        private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
        private static final int COLORDRAWABLE_DIMENSION = 1;
        private static final int DEFAULT_BORDER_WIDTH = 0;
        private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
        private final RectF mDrawableRect = new RectF();
        private final RectF mBorderRect = new RectF();
        private final Matrix mShaderMatrix = new Matrix();
        private final Paint mBitmapPaint = new Paint();
        private final Paint mBorderPaint = new Paint();
        private int mBorderColor = DEFAULT_BORDER_COLOR;
        private int mBorderWidth = DEFAULT_BORDER_WIDTH;
        private Bitmap mBitmap;
        private BitmapShader mBitmapShader;
        private int mBitmapWidth;
        private int mBitmapHeight;
        private float mDrawableRadius;
        private float mBorderRadius;
        private boolean mReady;
        private boolean mSetupPending;
    
        public CircleImageView(Context context) {
            super(context);
        }
    
        public CircleImageView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            super.setScaleType(SCALE_TYPE);
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
            mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
            mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
            a.recycle();
            mReady = true;
            if (mSetupPending) {
                setup();
                mSetupPending = false;
            }
        }
    
        @Override
        public ScaleType getScaleType() {
            return SCALE_TYPE;
        }
    
        @Override
        public void setScaleType(ScaleType scaleType) {
            if (scaleType != SCALE_TYPE) {
                throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            if (getDrawable() == null) {
                return;
            }
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            setup();
        }
    
        public int getBorderColor() {
            return mBorderColor;
        }
    
        public void setBorderColor(int borderColor) {
            if (borderColor == mBorderColor) {
                return;
            }
            mBorderColor = borderColor;
            mBorderPaint.setColor(mBorderColor);
            invalidate();
        }
    
        public int getBorderWidth() {
            return mBorderWidth;
        }
    
        public void setBorderWidth(int borderWidth) {
            if (borderWidth == mBorderWidth) {
                return;
            }
            mBorderWidth = borderWidth;
            setup();
        }
    
        @Override
        public void setImageBitmap(Bitmap bm) {
            super.setImageBitmap(bm);
            mBitmap = bm;
            setup();
        }
    
        @Override
        public void setImageDrawable(Drawable drawable) {
            super.setImageDrawable(drawable);
            mBitmap = getBitmapFromDrawable(drawable);
            setup();
        }
    
        @Override
        public void setImageResource(int resId) {
            super.setImageResource(resId);
            mBitmap = getBitmapFromDrawable(getDrawable());
            setup();
        }
    
        private Bitmap getBitmapFromDrawable(Drawable drawable) {
            if (drawable == null) {
                return null;
            }
            if (drawable instanceof BitmapDrawable) {
                return ((BitmapDrawable) drawable).getBitmap();
            }
            try {
                Bitmap bitmap;
                if (drawable instanceof ColorDrawable) {
                    bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
                } else {
                    bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
                }
                Canvas canvas = new Canvas(bitmap);
                drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
                drawable.draw(canvas);
                return bitmap;
            } catch (OutOfMemoryError e) {
                return null;
            }
        }
    
        private void setup() {
            if (!mReady) {
                mSetupPending = true;
                return;
            }
            if (mBitmap == null) {
                return;
            }
            mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            mBitmapPaint.setAntiAlias(true);
            mBitmapPaint.setShader(mBitmapShader);
            mBorderPaint.setStyle(Paint.Style.STROKE);
            mBorderPaint.setAntiAlias(true);
            mBorderPaint.setColor(mBorderColor);
            mBorderPaint.setStrokeWidth(mBorderWidth);
            mBitmapHeight = mBitmap.getHeight();
            mBitmapWidth = mBitmap.getWidth();
            mBorderRect.set(0, 0, getWidth(), getHeight());
            mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);
            mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);
            mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
            updateShaderMatrix();
            invalidate();
        }
    
        private void updateShaderMatrix() {
            float scale;
            float dx = 0;
            float dy = 0;
            mShaderMatrix.set(null);
            if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
                scale = mDrawableRect.height() / (float) mBitmapHeight;
                dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
            } else {
                scale = mDrawableRect.width() / (float) mBitmapWidth;
                dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
            }
            mShaderMatrix.setScale(scale, scale);
            mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);
            mBitmapShader.setLocalMatrix(mShaderMatrix);
        }
    
    }
    
    

    4)新建menu文件夹,menu/activity_main_drawer.xml

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <group android:checkableBehavior="single">
            <item
                android:id="@+id/nav_club"
                android:visible="false" />
            <item
                android:id="@+id/nav_new"
                android:icon="@drawable/ic_new_menu"
                android:title="@string/title_fragment_new" />
            <item
                android:id="@+id/nav_hot"
                android:icon="@drawable/ic_hot_menu"
                android:title="@string/title_fragment_hot" />
            <item
                android:id="@+id/nav_mine"
                android:icon="@drawable/ic_mine_menu"
                android:title="@string/title_fragment_mine"
                app:showAsAction="withText" />
    
        </group>
    </menu>
    
    

    5)SecondActivity.java

    public class SecondActivity extends AppCompatActivity {
        private NavigationView navigationView;
        private DrawerLayout drawer;
        private Toolbar toolbar;
        private ActionBarDrawerToggle mToggle;
    
        private NewFragment mNewFragment;
        private HotFragment mHotFragment;
        private MineFragment mMineFragment;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_second);
    
            toolbar = findViewById(R.id.toolbar);
            toolbar.setTitle(R.string.app_name);
            setSupportActionBar(toolbar);
            getSupportActionBar().setLogo(R.drawable.ic_logo);
    
            drawer = findViewById(R.id.drawer_layout);
            navigationView = findViewById(R.id.nav_view);
    
            mToggle = setupDrawerToggle();
            drawer.addDrawerListener(mToggle);
    
            setUpDrawerContent(navigationView);
    
            mNewFragment = NewFragment.newInstance(1);
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.setCustomAnimations(android.R.anim.fade_in,
                    android.R.anim.fade_out);
            fragmentTransaction.replace(R.id.frame, mNewFragment);
            fragmentTransaction.commitAllowingStateLoss();
    
        }
    
        private void setUpDrawerContent(NavigationView navigationView) {
            navigationView.setItemIconTintList(null);
            navigationView.setNavigationItemSelectedListener(
                    new NavigationView.OnNavigationItemSelectedListener() {
                        @Override
                        public boolean onNavigationItemSelected(MenuItem menuItem) {
                            selectDrawerItem(menuItem);
                            return true;
                        }
                    });
        }
    
        public void selectDrawerItem(MenuItem menuItem) {
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
            switch (menuItem.getItemId()) {
                case R.id.nav_new:
                    mNewFragment = NewFragment.newInstance(1);
                    ft.replace(R.id.frame,mNewFragment);
                    break;
    
                case R.id.nav_hot:
                    mHotFragment = HotFragment.newInstance(2);
                    ft.replace(R.id.frame,mHotFragment);
                    break;
    
                case R.id.nav_mine:
                    mMineFragment = MineFragment.newInstance(3);
                    ft.replace(R.id.frame,mMineFragment);
                    break;
    
                    default:
                        break;
            }
            ft.commit();
    
            if (menuItem.isChecked()) {
                menuItem.setChecked(false);
            } else {
                menuItem.setChecked(true);
            }
    
            // 改变状态
            menuItem.setChecked(true);
            // 改变标题
            toolbar.setTitle(menuItem.getTitle());
            // 关闭抽屉
            drawer.closeDrawers();
        }
    
        private ActionBarDrawerToggle setupDrawerToggle() {
            return new ActionBarDrawerToggle(this, drawer, toolbar, R.string.drawer_open, R.string.drawer_close);
        }
    
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            if (mToggle.onOptionsItemSelected(item)) {
                return true;
            }
            switch (item.getItemId()) {
                case android.R.id.home:
                    drawer.openDrawer(GravityCompat.START);
                    return true;
    
                    default:
                        break;
            }
            return super.onOptionsItemSelected(item);
        }
    
        @Override
        public void onPostCreate(Bundle savedInstanceState) {
            super.onPostCreate(savedInstanceState);
            mToggle.syncState();
        }
    
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            mToggle.onConfigurationChanged(newConfig);
        }
    }
    

    6)NewFragment.java (3 个Fragment 类似)

    public class NewFragment extends Fragment {
        private String[] nameDatas = new String[]{"智能","红润","日系","自然","艺术黑白","甜美","蜜粉","清新","夏日阳光","唯美","蜜粉",};
        private RecyclerView recyclerView;
        private CommonAdapter<String> adapter;
        public static NewFragment newInstance(int index) {
            NewFragment fragment = new NewFragment();
            Bundle bundle = new Bundle();
            bundle.putInt("index", index);
            fragment.setArguments(bundle);
            return fragment;
        }
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View view = inflater.inflate(R.layout.fragment_new, container, false);
            initData(view);
            return view;
        }
    
        private void initData(View view) {
            recyclerView = view.findViewById(R.id.rv);
            recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),3));
            adapter = new CommonAdapter<String>(getActivity(),R.layout.item, Arrays.asList(nameDatas)) {
                @Override
                protected void convert(ViewHolder holder, String s, int position) {
                    TextView title = holder.getConvertView().findViewById(R.id.tv_title);
                    title.setText(nameDatas[position]);
                }
            };
            recyclerView.setAdapter(adapter);
        }
    
    }
    
    

    7)fragment_new.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".fragment.HotFragment">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </FrameLayout>
    

    8)item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal">
    
        <android.support.v7.widget.CardView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:cardCornerRadius="5dp"
            app:cardElevation="3dp"
            android:layout_margin="8dp"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:android="http://schemas.android.com/apk/res/android">
    
            <ImageView
                android:id="@+id/iv_cover"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:scaleType="centerCrop"
                android:src="@mipmap/ic_launcher_round"/>
        </android.support.v7.widget.CardView>
    
        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:text="@string/hello_blank_fragment"
            android:layout_margin="10dp"/>
    
    </LinearLayout>
    

    4. 效果图

    nav.jpg

    相关文章

      网友评论

          本文标题:Android 小技巧之 NavigationView

          本文链接:https://www.haomeiwen.com/subject/aytlfctx.html