Android自定义NavigationView

2023-10-14 00:40

本文主要是介绍Android自定义NavigationView,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

做过Md风格app的朋友都应该用过Drawerlayout,而Drawerlayout的内容一般情况下是可以用support design包下的navigationview来实现。正如曾经的actionbar一样,看似非常完美了,,但当你希望去修改每个icon颜色或者每个文字颜色的时候却无法做到。正因如此本文主要介绍自定义navigationview的实现。还未使用过md风格控件的朋友可以先看看我另外一篇博客http://blog.csdn.net/zly921112/article/details/50733435

先来看我们要实现的效果
这里写图片描述
从navigationview源码发现,整个列表其实就是用recyclerview实现,那么同样我们也依葫芦画瓢,直接撸码

activity的布局文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/drawerlayout"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayout
        android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"></LinearLayout><android.support.v7.widget.RecyclerView
        android:id="@+id/rv_drawer"android:layout_width="@dimen/drawer_width"android:layout_height="match_parent"android:layout_gravity="start"android:background="@color/white" /></android.support.v4.widget.DrawerLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

这里并没有太多东西就是将drawerlayout的左侧菜单设置为recyclerview

activity代码

package com.zly.www.bzmh.activity;import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;import com.zly.www.bzmh.R;
import com.zly.www.bzmh.adapter.DrawerAdapter;
import com.zly.www.bzmh.base.BaseActivity;import butterknife.Bind;
import butterknife.ButterKnife;public class MainActivity extends BaseActivity {@Bind(R.id.drawerlayout)DrawerLayout drawerlayout;@Bind(R.id.rv_drawer)RecyclerView rvDrawer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);init();}private void init() {//抽屉初始化DrawerAdapter drawerAdapter = new DrawerAdapter();drawerAdapter.setOnItemClickListener(new MyOnItemClickListener());rvDrawer.setLayoutManager(new LinearLayoutManager(this));rvDrawer.setAdapter(drawerAdapter);}/*** drawer item 点击事件*/public class MyOnItemClickListener implements DrawerAdapter.OnItemClickListener {@Overridepublic void itemClick(DrawerAdapter.DrawerItemNormal drawerItemNormal) {switch (drawerItemNormal.titleRes) {case R.string.drawer_menu_home://首页break;case R.string.drawer_menu_rank://排行榜break;case R.string.drawer_menu_column://栏目break;case R.string.drawer_menu_search://搜索break;case R.string.drawer_menu_setting://设置break;case R.string.drawer_menu_night://夜间模式break;case R.string.drawer_menu_offline://离线break;}drawerlayout.closeDrawer(GravityCompat.START);}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

activity同样代码也并不多,给左侧的recyclerview设置adapter实现adapter中item点击接口

接下来就是adapter代码了,前方高能,在这里将会有比较多的代码了

package com.zly.www.bzmh.adapter;import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import com.facebook.drawee.view.SimpleDraweeView;
import com.zly.www.bzmh.R;import java.util.Arrays;
import java.util.List;/*** 抽屉adapter* Created by zly on 2016/3/30.*/
public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.DrawerViewHolder> {private static final int TYPE_DIVIDER = 0;private static final int TYPE_NORMAL = 1;private static final int TYPE_HEADER = 2;private List<DrawerItem> dataList = Arrays.asList(new DrawerItemHeader(),new DrawerItemNormal(R.mipmap.icon_drawerlayout_home, R.string.drawer_menu_home),new DrawerItemNormal(R.mipmap.icon_drawerlayout_rank, R.string.drawer_menu_rank),new DrawerItemNormal(R.mipmap.icon_drawerlayout_column, R.string.drawer_menu_column),new DrawerItemNormal(R.mipmap.icon_drawerlayout_search, R.string.drawer_menu_search),new DrawerItemNormal(R.mipmap.icon_drawerlayout_setting, R.string.drawer_menu_setting),new DrawerItemDivider(),new DrawerItemNormal(R.mipmap.icon_drawerlayout_night, R.string.drawer_menu_night),new DrawerItemNormal(R.mipmap.icon_drawerlayout_offline, R.string.drawer_menu_offline));@Overridepublic int getItemViewType(int position) {DrawerItem drawerItem = dataList.get(position);if (drawerItem instanceof DrawerItemDivider) {return TYPE_DIVIDER;} else if (drawerItem instanceof DrawerItemNormal) {return TYPE_NORMAL;}else if(drawerItem instanceof DrawerItemHeader){return TYPE_HEADER;}return super.getItemViewType(position);}@Overridepublic int getItemCount() {return (dataList == null || dataList.size() == 0) ? 0 : dataList.size();}@Overridepublic DrawerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {DrawerViewHolder viewHolder = null;LayoutInflater inflater = LayoutInflater.from(parent.getContext());switch (viewType) {case TYPE_DIVIDER:viewHolder = new DividerViewHolder(inflater.inflate(R.layout.item_drawer_divider, parent, false));break;case TYPE_HEADER:viewHolder = new HeaderViewHolder(inflater.inflate(R.layout.item_drawer_header, parent, false));break;case TYPE_NORMAL:viewHolder = new NormalViewHolder(inflater.inflate(R.layout.item_drawer_normal, parent, false));break;}return viewHolder;}@Overridepublic void onBindViewHolder(DrawerViewHolder holder, int position) {final DrawerItem item = dataList.get(position);if (holder instanceof NormalViewHolder) {NormalViewHolder normalViewHolder = (NormalViewHolder) holder;final DrawerItemNormal itemNormal = (DrawerItemNormal) item;normalViewHolder.iv.setBackgroundResource(itemNormal.iconRes);normalViewHolder.tv.setText(itemNormal.titleRes);normalViewHolder.view.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if(listener != null){listener.itemClick(itemNormal);}}});}else if(holder instanceof HeaderViewHolder){HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder;}}public OnItemClickListener listener;public void setOnItemClickListener(OnItemClickListener listener){this.listener = listener;}public interface OnItemClickListener{void itemClick(DrawerItemNormal drawerItemNormal);}//-------------------------item数据模型------------------------------// drawerlayout item统一的数据模型public interface DrawerItem {}//有图片和文字的itempublic class DrawerItemNormal implements DrawerItem {public int iconRes;public int titleRes;public DrawerItemNormal(int iconRes, int titleRes) {this.iconRes = iconRes;this.titleRes = titleRes;}}//分割线itempublic class DrawerItemDivider implements DrawerItem {public DrawerItemDivider() {}}//头部itempublic class DrawerItemHeader implements DrawerItem{public DrawerItemHeader() {}}//----------------------------------ViewHolder数据模型---------------------------//抽屉ViewHolder模型public class DrawerViewHolder extends RecyclerView.ViewHolder {public DrawerViewHolder(View itemView) {super(itemView);}}//有图标有文字ViewHolderpublic class NormalViewHolder extends DrawerViewHolder {public View view;public TextView tv;public ImageView iv;public NormalViewHolder(View itemView) {super(itemView);view = itemView;tv = (TextView) itemView.findViewById(R.id.tv);iv = (ImageView) itemView.findViewById(R.id.iv);}}//分割线ViewHolderpublic class DividerViewHolder extends DrawerViewHolder {public DividerViewHolder(View itemView) {super(itemView);}}//头部ViewHolderpublic class HeaderViewHolder extends DrawerViewHolder {private SimpleDraweeView sdv_icon;private TextView tv_login;public HeaderViewHolder(View itemView) {super(itemView);sdv_icon = (SimpleDraweeView) itemView.findViewById(R.id.sdv_icon);tv_login = (TextView) itemView.findViewById(R.id.tv_login);}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188

看着代码很多其实内容相对简单,这里也就是根据数据结构来加载对应的布局.并将条目点击事件暴露出来.这里为了方便我把数据直接写在了adapter内部,也可以在activity中直接从adapter构造方法传入.

分割线布局item_drawer_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="1dp"android:background="?android:attr/listDivider"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

头部布局item_drawer_header.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:fresco="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="@dimen/drawer_header_height"android:background="?attr/colorPrimary"android:orientation="vertical"><com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/sdv_icon"android:layout_width="@dimen/drawer_header_icon_size"android:layout_height="@dimen/drawer_header_icon_size"android:layout_centerVertical="true"android:layout_marginLeft="10dp"android:layout_marginTop="10dp"fresco:placeholderImage="@mipmap/icon_bg"fresco:roundAsCircle="true"/><TextView
        android:id="@+id/tv_login"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/sdv_icon"android:layout_marginLeft="10dp"android:layout_marginTop="10dp"android:text="登录"android:textColor="@color/white"android:textSize="@dimen/text_micro" />
</RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

列表布局item_drawer_normal.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="@dimen/drawer_item_height"android:gravity="center_vertical"android:orientation="horizontal"><ImageView
        android:id="@+id/iv"android:layout_width="@dimen/drawer_item_icon_size"android:layout_height="@dimen/drawer_item_icon_size"android:layout_marginLeft="@dimen/drawer_item_icon_leftmargin" /><TextView
        android:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="@dimen/drawer_item_text_leftmargin"android:textColor="@color/black"android:textSize="@dimen/text_small" />
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

资源文件
strings.xml

<resources><!-- drawer_menu_text--><string name="drawer_menu_home">首页</string><string name="drawer_menu_rank">排行榜</string><string name="drawer_menu_column">栏目</string><string name="drawer_menu_search">搜索</string><string name="drawer_menu_setting">设置</string><string name="drawer_menu_night">夜间模式</string><string name="drawer_menu_offline">离线</string>
</resources>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

dimens.xml

<resources><!-- drawerlayoutsize--><dimen name="drawer_width">260dp</dimen><dimen name="drawer_header_height">140dp</dimen><dimen name="drawer_header_icon_size">50dp</dimen><dimen name="drawer_item_icon_size">14dp</dimen><dimen name="drawer_item_height">44dp</dimen><dimen name="drawer_item_icon_leftmargin">14dp</dimen><dimen name="drawer_item_text_leftmargin">38dp</dimen><!-- 字体大小 --><dimen name="text_micro">12sp</dimen><dimen name="text_small">14sp</dimen><dimen name="text_medium">18sp</dimen><dimen name="text_large">20sp</dimen>
</resources>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

到此已经可以实现navigationview一样的效果了,但是到此还有一点小小的瑕疵就是条目点击的波纹效果

可以通过如下代码设置波纹的背景:
A: android:background=”?android:attr/selectableItemBackground”波纹有边界
B: android:background=”?android:attr/selectableItemBackgroundBorderless”波纹超出边界

效果A:
这里写图片描述

效果B:
这里写图片描述

显然只需要给列表布局加上android:background=”?android:attr/selectableItemBackground”即可完成点击波纹效果
而这个波纹的颜色我们可以通过修改styles.xml中colorControlHighlight(android:colorControlHighlight:设置波纹颜色)属性来调节动画颜色,从而可以适应不同的主题,但有一点要注意这个波纹效果只能在5.0以上有效,5.0以下就跟普通选择器一样.

转自zhuliyuan丶的博客:http://blog.csdn.net/zly921112/article/details/51056874

这篇关于Android自定义NavigationView的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/206952

相关文章

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

Python自定义异常的全面指南(入门到实践)

《Python自定义异常的全面指南(入门到实践)》想象你正在开发一个银行系统,用户转账时余额不足,如果直接抛出ValueError,调用方很难区分是金额格式错误还是余额不足,这正是Python自定义异... 目录引言:为什么需要自定义异常一、异常基础:先搞懂python的异常体系1.1 异常是什么?1.2

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

C语言自定义类型之联合和枚举解读

《C语言自定义类型之联合和枚举解读》联合体共享内存,大小由最大成员决定,遵循对齐规则;枚举类型列举可能值,提升可读性和类型安全性,两者在C语言中用于优化内存和程序效率... 目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.2.1 特点11.2.2 特点21.2.3 特点31.3 联合体的大小1

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期