带侧边栏字母索引的列表--重写Button类

前言

如图所示,侧边栏字母索引其实是一个Button类的按钮,点击该按钮上的某个字母,lietView会立刻跳转到对应的那一个字母的组,该效果通过重写Button类来实现.





需求分析

1.字母的绘制

需要将26个大写字母和‘#’,‘?’两个特殊字母按照固定的间隔绘制到按钮上。

2.点击按钮的功能

点击按钮是能够判断出选中的是哪个字母,并在列表上作出相应的显示。同时有弹窗提示。

3.点击按钮时的绘制

点击按钮时有颜色、字体的变化效果,松开按钮后又回复原样。


技术分析

重写onDraw函数,可以自定义按钮的绘制,在通过invalidate函数的调用,打到重绘的效果。

重写dispatchTouchEvent函数,自定义按钮的Down,Up事件的处理逻辑。

声明一个OnTouchSideButtonListener接口,带有两个回调函数,分别是onTouchSideButtonDown,onTouchSideButtonUP函数,在DOWN和UP事件的时候调用。

在Activity类里边实现上述这两个回调函数,把对列表显示的相关操作封装到这两个回调函数里。

实现过程

重写onDraw

1.getHeight(),getWidth()函数来获取按钮的宽和高,并计算出字母的间隔

2.paint实例来设置文字的相关样式属性

3.isTouch变量来判断当前是否按钮被点击

4.canvas实例真正决定了实行重绘

 

代码:

protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		int height = getHeight();
		int width = getWidth();
		int interval = height / (assort.length+1);//上下字母之间的间隔

		for (int i = 0, length = assort.length; i < length; i++) {
			paint.setTextSize(39);
			// 抗锯齿
			paint.setAntiAlias(true);
			// 默认粗体
			//paint.setTypeface(Typeface.DEFAULT_BOLD);
			// 白色
			if(!isTouch){//没有触摸的时候-->字体为半透明的黑色
				paint.setColor(Color.argb(51, 0, 0, 0));
				//paint.setColor(Color.alpha(150));
			}else{
				paint.setColor(Color.alpha(0));//透明度为0,即不透明
				paint.setColor(Color.WHITE);
			}
			
			if (i == selectIndex) {
				// 被选择的字母改变颜色和粗体
				paint.setColor(Color.WHITE);
				paint.setFakeBoldText(true);
				paint.setTextSize(43);
			}
			// 计算字母的X坐标
			float xPos = width / 2 - paint.measureText(assort[i]) / 2;
			// 计算字母的Y坐标
			float yPos = interval * i + interval;
			
			canvas.drawText(assort[i], xPos, yPos, paint);
			paint.reset();
		}

	}

声明接口OnTouchSideButtonListener

public interface OnTouchSideButtonListener {
		public void onTouchSideButtonDown(String selectedChar);
		public void onTouchSideButtonUP();
	}

同时声明一个接口对象和提供设置方法

// 字母监听器
private OnTouchSideButtonListener onTouch;

//实例化接口
public void setOnTouchSideButtonListener
(OnTouchSideButtonListener onTouch) {
		this.onTouch = onTouch;
	}

重写dispatchTouchEvent

1.根据event.getY()来获取点击的y轴坐标,并判断哪个字母被选中

2.如果是ACTION_DOWN事件,设置选中的字母下标,并调用    onTouchSideButtonDown函数

3.如果是ACTION_MOVE事件,更新选中的字母下表,并调用onTouchSideButtonDown函数

4.如果是ACTION_UP事件,重置相关信息,并调用onTouchSideButtonUP函数。

5.最后调用invalidate函数进行重绘。

6.Return 要返回true,这样才能截获后续的MOVEUP事件。

 

代码:

public boolean dispatchTouchEvent(MotionEvent event) {
		//改变背景色
		setBackgroundColor(Color.argb(224, 143, 141, 140));
		// TODO Auto-generated method stub
		float y = event.getY();
		//获得点击字母的下标,通过点击事件的坐标来计算出点击的字母
		int index = (int) (y / getHeight() * assort.length);
		if (index >= 0 && index < assort.length) {

			switch (event.getAction()) {
			case MotionEvent.ACTION_MOVE:
				// 如果滑动改变
				if (selectIndex != index) {
					selectIndex = index;
					if (onTouch != null) {
						//这个方法的代码在MainActivity里面实现了
						onTouch.onTouchSideButtonDown(assort[selectIndex]);
					}

				}
				break;
			case MotionEvent.ACTION_DOWN:
				//屏幕被按下
				isTouch=true;
				selectIndex = index;
				if (onTouch != null) {
					//这个方法是在OnTouchAssortListener接口定义的方法
					//它的具体代码在MainActivity里面实现
					onTouch.onTouchSideButtonDown(assort[selectIndex]);
					//onTouch.on
				}

				break;
			case MotionEvent.ACTION_UP:
				isTouch=false;
				setBackgroundResource(R.color.none);
				//
				if (onTouch != null) {
					onTouch.onTouchSideButtonUP();
				}
				selectIndex = -1;
				break;
			}
		} else {
			selectIndex = -1;
			if (onTouch != null) {
				onTouch.onTouchSideButtonUP();
			}
		}
		invalidate();//重绘

		
		return true;
	}


实现回调函数

1.onTouchSideButtonDown函数在DOWM事件时调用,起到的作用是(1)让列表显示选中的那个字母的组;(2)弹窗显示选中的字母。

2.onTouchSideButtonUP函数在UP事件时调用,让弹窗消失。

 

代码:

sideButton.setOnTouchSideButtonListener(new OnTouchSideButtonListener(){
//侧边栏按钮的监听函数
        	
 <span style="white-space:pre">	</span>//弹窗的布局文件
<span style="white-space:pre">	</span>View layoutView=LayoutInflater.from(Mp3ListActivity.this)
	.inflate(R.layout.alert_dialog_menu_layout, null);
  <span style="white-space:pre">	</span>//弹窗的字
	TextView text =(TextView) layoutView.findViewById(R.id.content);
	//弹窗
	PopupWindow popupWindow ;
	//接口要实现的两个方法
	@Override
	public void onTouchSideButtonDown(String selectedChar) {
	// TODO Auto-generated method stub
<span style="white-space:pre">	</span>int index=adapter.getHelper().getHashList().indexOfKey(selectedChar);
	if(index!=-1)
	{
		//显示选中的Group
		eListView.setSelectedGroup(index);;
	}
	if(popupWindow!=null){
		text.setText(selectedChar);
	}
	else
	{   
		popupWindow = new PopupWindow(layoutView,
					160, 160,false);
		// 显示在Activity的根视图中心
		popupWindow.showAtLocation(getWindow().getDecorView(),Gravity.CENTER, 0, 0);
	}
	text.setText(selectedChar);
}

	@Override
	public void onTouchSideButtonUP() {
		// TODO Auto-generated method stub
		if(popupWindow!=null)
			popupWindow.dismiss();
			popupWindow=null;
	}
        	
 });
}

代码模块结构图

跟之前的和在一起,就有如下图:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值