前段时间android项目中用到一个可以滑动的数量可变的导航栏,在网上也没找到合适的替代品,所以就自定义了个该控件,在此分享一下该控件,给有需要的人。
首先,来看看我们要实现的效果是什么样的。
上图就是我们要实现的最终效果图了,下面就说一下实现的过程。
考虑到能支持横向滑动,android提供的横向滑动的控件我选择了HorizontalScrollView作为基类,当然横向的ListView也是可以的,废话不多说先上代码。
public class CustomHorizontalScrollview extends HorizontalScrollView {
Context context;
int prevIndex = 0;
public CenterLockHorizontalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.setSmoothScrollingEnabled(true);
}
public void setAdapter(Context context, CustomListAdapter mAdapter) {
try {
fillViewWithAdapter(mAdapter);
} catch (ZeroChildException e) {
e.printStackTrace();
}
}
public void fillViewWithAdapter(CustomListAdapter mAdapter)
throws ZeroChildException {
if (getChildCount() == 0) {
throw new ZeroChildException(
"CenterLockHorizontalScrollView must have one child");
}
if (getChildCount() == 0 || mAdapter == null)
return;
ViewGroup parent = (ViewGroup) getChildAt(0);
parent.removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
parent.addView(mAdapter.getView(i, null, parent));
}
}
}
fillViewWithAdapter数据变化后的刷新控件,所以在调用了notifyDataSetChanged()之后还有再调用一下fillViewWithAdapter()这个方法才能刷新自定义控件。
public class CustomListAdapter extends ArrayAdapter implements View.OnClickListener{
private Context context;
private ArrayList list;
int layoutId;
Holder holder;
public View view;
public int currPosition = 0;
private DepartmentItemCallback callback;
public CustomListAdapter(Context context, int textViewResourceId,
ArrayList list) {
super(context, android.R.layout.simple_list_item_1, list);
this.context = context;
this.list = list;
layoutId = textViewResourceId;
}
@Override
public int getCount() {
return list.size();
}
@Override
public DepartmentBean getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = View.inflate(context, layoutId, null);
holder = new Holder();
holder.title = (TextView) convertView.findViewById(R.id.txtNewsSource);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
if (position == list.size() - 1) {
Drawable drawable = context.getResources().getDrawable(R.drawable.department_right);
drawable.setBounds(0,0,drawable.getMinimumWidth(),drawable.getMinimumHeight());
holder.title.setCompoundDrawables(null,null,drawable,null);
holder.title.setBackgroundColor(Color.rgb(75,165,255));
}else if (position == list.size() - 2) {
Drawable drawable = context.getResources().getDrawable(R.drawable.department_right1);
drawable.setBounds(0,0,drawable.getMinimumWidth(),drawable.getMinimumHeight());
holder.title.setCompoundDrawables(null,null,drawable,null);
holder.title.setBackgroundColor(Color.rgb(234,234,234));
}else {
Drawable drawable = context.getResources().getDrawable(R.drawable.department_right0);
drawable.setBounds(0,0,drawable.getMinimumWidth(),drawable.getMinimumHeight());
holder.title.setCompoundDrawables(null,null,drawable,null);
holder.title.setBackgroundColor(Color.rgb(234,234,234));
}
String newsSource = getItem(position).getName();
holder.title.setText(newsSource);
holder.title.setTag(position);
holder.title.setOnClickListener(this);
Log.v("Test", "lo frm newsadpater");
return convertView;
}
@Override
public void onClick(View view) {
int id = view.getId();
if (id == R.id.txtNewsSource) {
callback.onClick((Integer) view.getTag());
}
}
private class Holder {
public TextView title;
}
public int getCurrentPosition(){
return currPosition;
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
Adapter也贴一下,关于这个Adapter继承BaseAdapter或者其他的都行,看自己用什么方便用什么,要点在于Adapter的getView方法中位置不同,就要修改背景了。这里也就2个背景色,最后一个与其他的是有差别的,然后再是每个item的形状都是不规则的,所以就把它分为两部分,一部分用颜色填充另一部分使用png图片放置到右侧就能达到想要的效果了。那么单个的item的布局就很简单的了,右侧的图片直接使用drawableRight,下面item布局代码放上代码。
改变右侧png图片在adapter中已经写了, setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)方法四个参数分别是将图置于控件左、上、右、下。drawable.setBounds(0,0,drawable.getMinimumWidth(),drawable.getMinimumHeight()),setBounds()这个方法不能少,要获取到图的尺寸才能画上图,不然不会生效。
最后放上源代码,也可以访问我的github 点击查看最新分享。