android仿微信滑动切换最终实现效果:
大体思路:
1. 主要使用两个自定义view配合实现; 底部图标加文字为一个自定义view,底部导航栏为一个载体,根据需要来添加底部图标;
2. 底部导航栏的设置方法类似于tablayout的关联,view需要创建关联方法,用来关联viewpager;
3. 通过关联方法获取viewpager实例后,根据viewpager页面数创建底部导航栏的图标按钮;
代码实现:
1. 新建第一个自定义view, 图标 + 文字 的底部按钮;
/**
* 自定义控件,该控件为底部导航栏中的图标
* created by mrzheng on 2017/8/2.
*/
public class tabview extends linearlayout {
botbean mbean;
private textview title;
private imageview iconimage;
/**
* 引用此控件,只能通过new 方法;接收一个tabview
* @param context
*/
public tabview(context context, botbean bean) {
super(context);
this.mbean = bean;
initview();
}
/**
* 初始化布局
*/
public void initview() {
setorientation(vertical);
setgravity(gravity.center);
//添加小图标
iconimage = new imageview(getcontext());
linearlayout.layoutparams layoutparams = new linearlayout.layoutparams(viewgroup.layoutparams.wrap_content
, viewgroup.layoutparams.wrap_content);
iconimage.setlayoutparams(layoutparams);
iconimage.setimageresource(mbean.getuncheckedid());
drawable drawable = getcontext().getresources().getdrawable(mbean.getuncheckedid());
drawable wrapdrawable = drawablecompat.wrap(drawable);
drawablecompat.settintlist(wrapdrawable, colorstatelist.valueof(color.black));
iconimage.setimagedrawable(wrapdrawable);
addview(iconimage);
//标题
title = new textview(getcontext());
linearlayout.layoutparams titleparams = new layoutparams(layoutparams.wrap_content,
layoutparams.wrap_content);
title.setlayoutparams(titleparams);
title.settext(mbean.getcontent());
addview(title);
}
//判断选择状态,改变图标
//供外部调用
public void setselected(boolean isselected) {
if (mbean == null) {
return;
}
if (isselected) {
if (iconimage != null) {
//使用颜色过滤器,改变选中时的颜色
drawable drawable = getcontext().getresources().getdrawable(mbean.getuncheckedid());
drawable wrapdrawable = drawablecompat.wrap(drawable);
drawablecompat.settintlist(wrapdrawable, colorstatelist.valueof(color.green));
iconimage.setimagedrawable(wrapdrawable);
title.settextcolor(color.green);
}
} else {
if (title != null) {
// iconimage.setimageresource(mbean.getuncheckedid());
drawable drawable = getcontext().getresources().getdrawable(mbean.getuncheckedid());
drawable wrapdrawable = drawablecompat.wrap(drawable);
drawablecompat.settintlist(wrapdrawable, colorstatelist.valueof(color.black));
iconimage.setimagedrawable(wrapdrawable);
title.settextcolor(color.gray);
}
}
}
}
2. 创建第二个自定义view,该view为底部导航栏载体,根据 关联的viewpager页面 个数创建 底部导航栏图标;
/**
* 该控件为底部导航栏图标载体
* created by mrzheng on 2017/8/2.
*/
public class bottomview extends linearlayout {
private viewpager vp;
bottompagechangelistener mbottompagechangelistener;
public bottomview(context context) {
super(context);
}
public bottomview(context context, @nullable attributeset attrs) {
super(context, attrs);
}
public bottomview(context context, @nullable attributeset attrs, int defstyleattr) {
super(context, attrs, defstyleattr);
}
/**
* 同tablayout用法相似,需要与viewpager进行绑定
*/
public void setviewpager(viewpager viewpager, arraylist botbeen,bottompagechangelistener bottompagechangelistener) {
if (viewpager == null) {
return;
}
vp = viewpager;
mbottompagechangelistener = bottompagechangelistener;
inittabview(botbeen);
//设置viewpager的点击事件
vp.addonpagechangelistener(new viewpager.simpleonpagechangelistener(){
@override
public void onpageselected(int position) {
for (int i = 0; i < getchildcount(); i++) {
getchildat(i).setselected((position == i ? true : false));
}
if (mbottompagechangelistener != null) {
mbottompagechangelistener.onpagechangelistener(position);
}
}
});
}
/**
* 初始化底部导航栏,viewpager有多少页,就创建多少个图标
*/
public void inittabview(arraylist botbeen) {
setgravity(horizontal);
for (int i = 0; i < botbeen.size(); i++) {
botbean bean = botbeen.get(i);
tabview tabview = new tabview(getcontext(), bean);
linearlayout.layoutparams params = new linearlayout.layoutparams(viewgroup.layoutparams.wrap_content
, viewgroup.layoutparams.wrap_content);
params.weight = 1;
params.gravity = gravity.center;
tabview.setlayoutparams(params);
//为每个view设置点击事件,点击跳转过去
final int finali = i;
tabview.setonclicklistener(new onclicklistener() {
@override
public void onclick(view view) {
vp.setcurrentitem(finali);
}
});
//设置一开始选中状态
if (i == 0) {
tabview.setselected(true);
//由于初始化时,onpageselected()选中方法并没有的到执行,所以主动去调用回调方法
if (mbottompagechangelistener != null) {
mbottompagechangelistener.onpagechangelistener(i);
}
}
addview(tabview);
}
}
/**
* 提供接口回调方法,每次滑动都通知外界
*/
public interface bottompagechangelistener{
void onpagechangelistener(int position);
}
}
3. 添加 图标自定义类, 该类封装着底部导航栏中每一个选项的的图标和文字,将该类型对象添加到集合中,用于给底部导航栏设置图标;
/**
* 底部导航栏的封装类,该类对象用于在底部导航栏添加对应图标和文字
* created by mrzheng on 2017/8/2.
*/
public class botbean {
string content;//图标名字
int uncheckedid;//未选中时的图标
public botbean(string content, int uncheckedid) {
this.content = content;
this.uncheckedid = uncheckedid;
}
public string getcontent() {
return content;
}
public void setcontent(string content) {
this.content = content;
}
public int getuncheckedid() {
return uncheckedid;
}
public void setuncheckedid(int uncheckedid) {
this.uncheckedid = uncheckedid;
}
}
自定义view实现完成,在fragment或activity中使用该view:
1. 在布局文件中添加:
android:id="@+id/bottom"
android:layout_width="match_parent"
android:layout_height="60dp">
2. 在活动或碎片中添加:
public class mainactivity extends appcompatactivity {
arraylist mfragments;
arraylist mitemicon;//存放底部图标和文字
private textview tv;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
mfragments = new arraylist<>();
mitemicon = new arraylist<>();
mfragments.add(new textfragment());
mfragments.add(new textfragment());
mfragments.add(new textfragment());
mfragments.add(new textfragment());
mitemicon.add(new botbean("首页", r.mipmap.ic_home2));
mitemicon.add(new botbean("通讯录", r.mipmap.ic_study2));
mitemicon.add(new botbean("发现", r.mipmap.ic_found2));
mitemicon.add(new botbean("我的", r.mipmap.ic_me2));
viewpager vp = (viewpager) findviewbyid(r.id.vp);
vp.setadapter(new fadapter(getsupportfragmentmanager()));
tv = (textview) findviewbyid(r.id.tv);
bottomview bottom = (bottomview) findviewbyid(r.id.bottom);
bottom.setviewpager(vp, mitemicon, new bottomview.bottompagechangelistener() {
@override
public void onpagechangelistener(int position) {
//滑动后的回调
tv.settext(mitemicon.get(position).getcontent());
}
});
}
/**
* 适配器
*/
class fadapter extends fragmentpageradapter {
public fadapter(fragmentmanager fm) {
super(fm);
}
@override
public fragment getitem(int position) {
return mfragments.get(position);
}
@override
public int getcount() {
return mfragments.size();
}
}
}
总结:该代码耦合度较高,有些代码可能不太合理;欢迎大牛们给出合理建议;
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。