android动态侧滑菜单,【Android】侧滑菜单的实现方式

对于侧滑菜单的实现方式,一种比较标准化的实现方式是DrawerLayout + NavigationView的方式,该方式的实现过程可以看我的另一篇博客【Android】Material Design 之三 NavigationView 使用?。然而,DrawerLayout + NavigationView的侧滑实现有个缺点就是,菜单的布局是单一的,只有一个图标、一个标题,当我们想要实现丰富的菜单布局时(如下图所示)该方法就不能满足我们的需要,此时,我们需要考虑如何让侧滑的菜单能有丰富样式的布局,本篇博客就来解决这个问题。

20180917162954843

?实现上图中左右两种样式的侧滑菜单,同样需要DrawerLayout布局的支持,DrawerLayout布局中可有3个子布局,第一个布局必须为主界面,其他2个布局就是左、右两侧的布局,左右两个只放一个也可以。

这里我们在布局中左右两侧布局都使用,可以同时分别在左右两边布局中实现上图中两种侧滑菜单样式,只需要在2个子布局添加属性android:layout_gravity,值为start从左测滑出菜单,值为end从右侧滑出菜单。

上图中,左边是使用列表ListView控件实现菜单样式,右边是用网格GridView控件实现菜单样式,上方都是一个头布局。

布局文件:

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MyMenuViewActivity">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="center">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="这是自定义侧滑菜单"/>

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:layout_gravity="start">

android:id="@+id/lv"

android:background="#ffffff"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:divider="#cacaca"

android:dividerHeight="2dp"

android:scrollbars="none">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:layout_gravity="end">

android:id="@+id/gv"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:scrollbars="none"

android:numColumns="2"

android:background="#808080"

android:horizontalSpacing="2dp"

android:verticalSpacing="2dp">

头布局header.xml:

android:layout_width="match_parent"

android:layout_height="180dp"

android:orientation="vertical"

android:gravity="center"

android:background="@drawable/header_bg">

android:layout_width="50dp"

android:layout_height="50dp"

android:src="@drawable/avator"/>

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="摸爬滚打的程序媛"

android:padding="5dp"

android:textColor="#FFFFFF"/>

头布局中的背景?header_bg.xml:

android:angle="45"

android:startColor="#e965d3"

android:endColor="#ac68e7"/>

?listview_item.xml布局:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="5dp">

android:id="@+id/iv"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_centerVertical="true"/>

android:id="@+id/tv"

android:layout_toRightOf="@+id/iv"

android:layout_marginLeft="5dp"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="15sp"

android:textColor="#000000"

android:layout_centerVertical="true"/>

android:layout_alignParentRight="true"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/ic_arrow_right"

android:layout_centerVertical="true"/>

?gridview_item.xml布局:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="20dp"

android:orientation="vertical"

android:gravity="center"

android:background="#FFFFFF">

android:id="@+id/iv"

android:layout_width="50dp"

android:layout_height="50dp" />

android:id="@+id/tv"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textSize="15sp"

android:textColor="#000000"/>

既然使用了列表,就需要适配器进行数据的填充,自定义可复用的适配器MyBaseAdapter.java:

public abstract class MyBaseAdapter extends BaseAdapter{

private List dataList;

private int layoutResId; //列表item的布局id

public MyBaseAdapter(List dataList,int layoutResId) {

this.dataList = dataList;

this.layoutResId=layoutResId;

}

//获取数据个数

@Override

public int getCount() {

return dataList != null ? dataList.size() : 0;

}

//获取指定位置的数据

@Override

public Object getItem(int i) {

return dataList.get(i);

}

//获取指定位置下标

@Override

public long getItemId(int i) {

return i;

}

//获取item布局

@Override

public View getView(int i, View view, ViewGroup viewGroup) {

ViewHolder viewHolder=ViewHolder.bind(viewGroup.getContext(),view,viewGroup,layoutResId,i);

bindView(viewHolder,dataList.get(i));

return viewHolder.getItemView();

}

public abstract void bindView(ViewHolder holder,T data);

public static class ViewHolder{

private SparseArray views; //存放ListView的子项item中的控件view

private View convertView; //存放convertView

private int position; //游标

private Context context; //上下文

//构造方法,完成相关初始化

private ViewHolder(Context context,ViewGroup parent,int layoutResId){

views=new SparseArray<>();

this.context=context;

convertView=LayoutInflater.from(context).inflate(layoutResId,parent,false);

convertView.setTag(this);

}

//绑定ViewHolder和Item

public static ViewHolder bind(Context context,View convertView,ViewGroup parent,int layoutResId,int position){

ViewHolder viewHolder;

if(convertView==null){

viewHolder=new ViewHolder(context,parent,layoutResId);

}else{

viewHolder= (ViewHolder) convertView.getTag();

viewHolder.convertView=convertView;

}

viewHolder.position=position;

return viewHolder;

}

//根据id获取集合中保存的控件

@SuppressWarnings("unchecked")

private T getView(int resId){

T t= (T) views.get(resId);

if(t==null){

t=convertView.findViewById(resId);

views.put(resId,t);

}

return t;

}

//获取子项的View

public View getItemView(){

return convertView;

}

//获取子项位置

public int getItemPosition(){

return position;

}

//文本控件 设置文字

public void setText(int resId, CharSequence text){

View view=getView(resId);

if (view instanceof TextView) {

((TextView) view).setText(text);

}

}

//图片控件或者可设置背景图片的控件 设置图片

public void setImageResource(int resId, int drawableResId){

View view=getView(resId);

if (view instanceof ImageView) {

((ImageView) view).setImageResource(drawableResId);

}else{

view.setBackgroundResource(drawableResId);

}

}

//可监听控件 设置点击监听

public ViewHolder setOnClickListener(int resId,View.OnClickListener listener){

getView(resId).setOnClickListener(listener);

return this;

}

//控件设置可见

public ViewHolder setVisibility(int resId,int visible){

getView(resId).setVisibility(visible);

return this;

}

//设置标签

public ViewHolder setTag(int resId,Object obj){

getView(resId).setTag(obj);

return this;

}

//其他方法可自行扩展

}

}

?定义填充的数据bean:

public class MenuBean {

private int imgResId;

private String title;

public MenuBean(int imgResId, String title) {

this.imgResId = imgResId;

this.title = title;

}

public int getImgResId() {

return imgResId;

}

public void setImgResId(int imgResId) {

this.imgResId = imgResId;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

}

?代码如下:

public class MyMenuViewActivity extends AppCompatActivity {

private ListView listView;

private GridView gridView;

private MyBaseAdapter lvAdapter;

private MyBaseAdapter gvAdapter;

private List list;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_snavigation_view);

listView=findViewById(R.id.lv);

gridView=findViewById(R.id.gv);

? //数据源

list=new ArrayList<>();

list.add(new MenuBean(R.drawable.ic_menu_book,"头条"));

list.add(new MenuBean(R.drawable.ic_menu_star,"收藏"));

list.add(new MenuBean(R.drawable.ic_menu_argu,"论坛"));

list.add(new MenuBean(R.drawable.ic_menu_load,"下载"));

list.add(new MenuBean(R.drawable.ic_menu_rili,"日历"));

list.add(new MenuBean(R.drawable.ic_menu_level,"等级"));

list.add(new MenuBean(R.drawable.ic_menu_cloud,"云空间"));

list.add(new MenuBean(R.drawable.ic_menu_help,"帮助"));

lvAdapter=new MyBaseAdapter(list,R.layout.listview_item) {

@Override

public void bindView(ViewHolder holder, MenuBean data) {

holder.setImageResource(R.id.iv,data.getImgResId());

holder.setText(R.id.tv,data.getTitle());

}

};

gvAdapter=new MyBaseAdapter(list,R.layout.gridview_item) {

@Override

public void bindView(ViewHolder holder, MenuBean data) {

holder.setImageResource(R.id.iv,data.getImgResId());

holder.setText(R.id.tv,data.getTitle());

}

};

listView.setAdapter(lvAdapter);

gridView.setAdapter(gvAdapter);

}

}

?运行效果就如开始的那张图,ListView的分割线可以通过下面两个属性实现:

android:divider="#cacaca" //分割线颜色

android:dividerHeight="2dp" //分割线高度

GridView的分割线实现,首先在设置其item背景,然后在其控件中?设置下面三个属性:

android:background="#808080" //GridView背景颜色

android:horizontalSpacing="2dp" //列之间的水平间隔

android:verticalSpacing="2dp //行之间的垂直间隔

这里再补充说一下,使用ListView实现侧滑菜单时,除了可以在布局中添加头布局

,还可以使用listview.addHeaderView()方法添加头文件,效果和在布局中添加的效果有些不同,如下图:

View view=LayoutInflater.from(this).inflate(R.layout.header,null);

listView.addHeaderView(view);

?

20180917170355910

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值