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

前段时间android项目中用到一个可以滑动的数量可变的导航栏,在网上也没找到合适的替代品,所以就自定义了个该控件,在此分享一下该控件,给有需要的人。

首先,来看看我们要实现的效果是什么样的。

Android自定义控件,可以滑动的导航栏(Navigation Bar)_第1张图片

      上图就是我们要实现的最终效果图了,下面就说一下实现的过程。

考虑到能支持横向滑动,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 点击查看最新分享。

你可能感兴趣的:(Android自定义控件)