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>
网友评论