赞
踩
NavigationView,导航视图,比如QQ的侧滑菜单,如下图,分为head和menu上下两部分head【图片,昵称,uid】menu【下面的菜单】
添加implementation 'com.android.support:design:29.+'
圆形头像CircleImageView或者是
//实现图片圆形化
compile 'de.hdodenhof:circleimageview:2.1.0'2.
-
- /**
- 圆形头像
- * */
- 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 = 2;
-
- private static final int DEFAULT_BORDER_WIDTH = 0;
- private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
- private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
- private static final boolean DEFAULT_BORDER_OVERLAY = false;
-
- 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 final Paint mFillPaint = new Paint();
-
- private int mBorderColor = DEFAULT_BORDER_COLOR;
- private int mBorderWidth = DEFAULT_BORDER_WIDTH;
- private int mFillColor = DEFAULT_FILL_COLOR;
-
- private Bitmap mBitmap;
- private BitmapShader mBitmapShader;
- private int mBitmapWidth;
- private int mBitmapHeight;
-
- private float mDrawableRadius;
- private float mBorderRadius;
-
- private ColorFilter mColorFilter;
-
- private boolean mReady;
- private boolean mSetupPending;
- private boolean mBorderOverlay;
-
- public CircleImageView(Context context) {
- super(context);
-
- init();
- }
-
- public CircleImageView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
-
- mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
- mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
- mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
- mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);
-
- a.recycle();
-
- init();
- }
-
- private void init() {
- super.setScaleType(SCALE_TYPE);
- 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
- public void setAdjustViewBounds(boolean adjustViewBounds) {
- if (adjustViewBounds) {
- throw new IllegalArgumentException("adjustViewBounds not supported.");
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (mBitmap == null) {
- return;
- }
-
- if (mFillColor != Color.TRANSPARENT) {
- canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mFillPaint);
- }
- canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mBitmapPaint);
- if (mBorderWidth != 0) {
- canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, 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(@ColorInt int borderColor) {
- if (borderColor == mBorderColor) {
- return;
- }
-
- mBorderColor = borderColor;
- mBorderPaint.setColor(mBorderColor);
- invalidate();
- }
-
- public void setBorderColorResource(@ColorRes int borderColorRes) {
- setBorderColor(getContext().getResources().getColor(borderColorRes));
- }
-
- public int getFillColor() {
- return mFillColor;
- }
-
- public void setFillColor(@ColorInt int fillColor) {
- if (fillColor == mFillColor) {
- return;
- }
-
- mFillColor = fillColor;
- mFillPaint.setColor(fillColor);
- invalidate();
- }
-
- public void setFillColorResource(@ColorRes int fillColorRes) {
- setFillColor(getContext().getResources().getColor(fillColorRes));
- }
-
- public int getBorderWidth() {
- return mBorderWidth;
- }
-
- public void setBorderWidth(int borderWidth) {
- if (borderWidth == mBorderWidth) {
- return;
- }
-
- mBorderWidth = borderWidth;
- setup();
- }
-
- public boolean isBorderOverlay() {
- return mBorderOverlay;
- }
-
- public void setBorderOverlay(boolean borderOverlay) {
- if (borderOverlay == mBorderOverlay) {
- return;
- }
-
- mBorderOverlay = borderOverlay;
- 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(@DrawableRes int resId) {
- super.setImageResource(resId);
- mBitmap = getBitmapFromDrawable(getDrawable());
- setup();
- }
-
- @Override
- public void setImageURI(Uri uri) {
- super.setImageURI(uri);
- mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null;
- setup();
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- if (cf == mColorFilter) {
- return;
- }
-
- mColorFilter = cf;
- mBitmapPaint.setColorFilter(mColorFilter);
- invalidate();
- }
-
- 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 (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- private void setup() {
- if (!mReady) {
- mSetupPending = true;
- return;
- }
-
- if (getWidth() == 0 && getHeight() == 0) {
- return;
- }
-
- if (mBitmap == null) {
- invalidate();
- 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);
-
- mFillPaint.setStyle(Paint.Style.FILL);
- mFillPaint.setAntiAlias(true);
- mFillPaint.setColor(mFillColor);
-
- mBitmapHeight = mBitmap.getHeight();
- mBitmapWidth = mBitmap.getWidth();
-
- mBorderRect.set(0, 0, getWidth(), getHeight());
- mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
-
- mDrawableRect.set(mBorderRect);
- if (!mBorderOverlay) {
- mDrawableRect.inset(mBorderWidth, mBorderWidth);
- }
- mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
-
- 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() / mBitmapHeight;
- dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
- } else {
- scale = mDrawableRect.width() / mBitmapWidth;
- dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
- }
-
- mShaderMatrix.setScale(scale, scale);
- mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
-
- mBitmapShader.setLocalMatrix(mShaderMatrix);
- }
-
- }

res目录下values创建添加
<declare-styleable name="CircleImageView"> <attr name="civ_border_width" format="dimension" /> <attr name="civ_border_color" format="color" /> <attr name="civ_border_overlay" format="boolean" /> <attr name="civ_fill_color" format="color" /> </declare-styleable>
主页布局
- <?xml version="1.0" encoding="utf-8"?>
- <androidx.drawerlayout.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:orientation="vertical"
- tools:context=".activity.MainActivity">
-
-
- <!--可以在程序中根据抽屉菜单 切换Fragment-->
-
-
- <FrameLayout
- android:id="@+id/frame_layout"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
-
- <!--左边抽屉菜单宽高什么的可以自己调-->
- <com.google.android.material.navigation.NavigationView
- android:id="@+id/nv_menu_left"
- android:layout_width="140dp"
- android:layout_height="match_parent"
- android:layout_gravity="left"
- app:headerLayout="@layout/header"
- app:menu="@menu/menu_drawer_left" />
-
-
- </androidx.drawerlayout.widget.DrawerLayout>

NavitationView常用属性
android:layout_gravity="left"设置在哪边划出
app:headerLayout="@layout/header"设置布局的文件头,此案例是那个圆形头像,昵称和uid
app:menu="@menu/menu_drawer_left"设置点击项,就是档案馆那三个
header布局
<?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="240dp" android:background="@mipmap/ic_app_top_bg" android:orientation="vertical"> <CircleImageView android:layout_width="@dimen/dp_90" android:id="@+id/cv_user_head" android:layout_height="@dimen/dp_90" android:layout_marginLeft="@dimen/dp_20" android:layout_marginTop="36dp" android:layout_marginBottom="16dp" android:src="@mipmap/ic_app"/> <TextView android:id="@+id/tv_user_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/dp_20" android:text="昵称" android:textColor="@color/white" android:textSize="@dimen/sp_14" /> <LinearLayout android:id="@+id/ll_copy_uid" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/dp_20" android:layout_marginTop="@dimen/dp_10" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="木偶MUO:" android:textColor="@color/color_212121" android:textSize="@dimen/sp_12" /> <TextView android:id="@+id/tv_user_uuid" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:textColor="@color/color_212121" android:textSize="@dimen/sp_12" /> </LinearLayout> </LinearLayout>
menu_drawer_left布局【res目录下创建menu目录下创建menu_drawer_left布局】
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/nav_home" android:icon="@mipmap/ic_app" android:title="关于我们" /> <item android:id="@+id/nav_messages" android:icon="@mipmap/ic_fun" android:title="反馈" /> <item android:id="@+id/nav_friends" android:icon="@mipmap/ic_muo" android:title="档案馆" /> </menu>
public class MainActivity extends BaseActivity {
@BindView(R.id.nv_menu_left)
NavigationView nvMenuLeft;
@BindView(R.id.drawer_layout)
DrawerLayout drawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//实例化的NavigationView控件
nvMenuLeft.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_home:
startActivity(new Intent(MainActivity.this, AboutActivity.class));
break;
case R.id.nav_messages:
startActivity(new Intent(MainActivity.this, IdearActivity.class));
break;
case R.id.nav_friends:
startActivity(new Intent(MainActivity.this, TextImgActivity.class));
break;
}
drawerLayout.closeDrawers();
return false;
}
});
}
//抽屉布局的左侧头部初始化控件
TextView mUserUid;
LinearLayout llCopyUid;
TextView mUserName;
CircleImageView mUserAvatar;
private void initUserInfo() {
// 获取头部视图
View headerView = nvMenuLeft.getHeaderView(0);
//头部初始化控件
mUserAvatar = headerView.findViewById(R.id.cv_user_head);
mUserName = headerView.findViewById(R.id.tv_user_name);
mUserUid = headerView.findViewById(R.id.tv_user_uuid);
llCopyUid = headerView.findViewById(R.id.ll_copy_uid);
mUserUid.setText(StringCache.get("uid"));
//点击事件
mUserAvatar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//关闭抽屉布局
drawerLayout.closeDrawers();
//打开布局,参数Gravity.LEFTGravity.LEFT to move the left drawer or Gravity.RIGHT for the right.
// GravityCompat.START or GravityCompat.END may also be used.
// drawerLayout.openDrawer(Gravity.LEFT);
}
});
//头像展示
Glide.with(MainActivity.this).load(R.mipmap.ic_app).apply(RequestOptions.circleCropTransform()).into(mUserAvatar);
}
}
}
大致的功能基本都在这边了,下面就是自己的逻辑实现了,应该是很明了的一篇文章了,后续需要的话可以继续补充功能
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。