Android自定义控件,可以滑动的导航栏(Navigation Bar)

前段时间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()这个方法才能刷新自定义控件。
<span style="font-family: 宋体; font-size: 10.5pt;"></span><pre name="code" class="html">public class CustomListAdapter extends ArrayAdapter<DepartmentBean> implements View.OnClickListener{
	private  Context context;
	private ArrayList<DepartmentBean> list;
	int layoutId;
	Holder holder;
	public View view;
	public int currPosition = 0;
	private DepartmentItemCallback callback;
	public CustomListAdapter(Context context, int textViewResourceId,
			ArrayList<DepartmentBean> 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();
	}
}


 
<span style="white-space:pre">	</span>Adapter也贴一下,关于这个Adapter继承BaseAdapter或者其他的都行,看自己用什么方便用什么,要点在于Adapter的getView方法中位置不同,就要修改背景了。这里也就2个背景色,最后一个与其他的是有差别的,然后再是每个item的形状都是不规则的,所以就把它分为两部分,一部分用颜色填充另一部分使用png图片放置到右侧就能达到想要的效果了。那么单个的item的布局就很简单的了,右侧的图片直接使用drawableRight,下面item布局代码放上代码。
<pre name="code" class="java"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="42dp"
    android:layout_gravity="center"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/txtNewsSource"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:background="#4ba5ff"
        android:text="移动部门"
        android:paddingLeft="10dp"
        android:drawableRight="@drawable/department_right"
        />
</RelativeLayout>

改变右侧png图片在adapter中已经写了, setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom)方法四个参数分别是将图置于控件左、上、右、下。drawable.setBounds(0,0,drawable.getMinimumWidth(),drawable.getMinimumHeight()),setBounds()这个方法不能少,要获取到图的尺寸才能画上图,不然不会生效。

最后放上源代码,也可以访问我的github 点击查看最新分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值