说明
在许多APP应用中,您可以看到侧栏的使用。 例如微信、QQ、美团等。 最常见的做法是在通讯录中按A-z对联系人进行排序。 侧边栏主要便于用户索引字母。 资料链接: http://www.void cn.com/article/p-oprssxij-BHS.html
今天实现的控件的效果如下图所示。
图纸:
1.Sidebar的JAVA类文件
package com.example.mysidebar;
import Android.annotation.targetapi;
导入安卓. content.context;
import android.graphics.Canvas;
import android.graphics.Color;
导入安卓. graphics.paint;
import Android.graphics.typeface;
导入安卓. graphics.drawable.color drawable;
import android.os.Build;
import Android.util.attributes et;
导入安卓. view.motion event;
导入安卓. view.view;
import Android .构件. textview;
import org.w3c.dom.Attr;
/* * createdbyadministratoron 2016/7/70007.* /
公共类sidebar扩展视图{
公共密码(上下文上下文) {
super (上下文;
}
公共sidebar (上下文上下文,属性et attrs ) {
super (上下文、attrs );
}
公共sidebar (上下文上下文,属性et attrs,int defStyleAttr ) {
super (上下文、attrs、defStyleAttr );
}
/**触摸字符索引已更改的回调接口*/
privateonlettertouchedchangelisteneronlettertouchedchangelistener=空;
//侧栏的字母表示
private String[] alphabet={
' a '、' b '、' c '、' d '、' e '、' f '、' g '、' h '、' I ',
包括: j、k、l、m、n、o、p、q、s、t、u、v,
' w ',' x ',' y ',' z ',' # '
(;
//变量currentChoosenAlphabetIndex用于标记当前手指触摸的字符索引的alphabet数组中的下标
privateintcurrentchoosenalphabetindex=-1;
//定义画笔
隐私绘制点=new paint (;
如果手指在SideBar上滑动,则还有一个TextView,它显示当前手指所接触的字母的索引,因此还需要另一个属性
专用textviewtextviewdialog=null;
/* *显示sidebar文字的textview * @ paramtextviewdialog * /
publicvoidsettextviewdialog (文本视图文本视图对话框)。
this.textview dialog=textview dialog;
}
/**列表控件的绘制方法*从上到下在指定区域绘制要绘制的字符*如果是选定字符,则高亮显示*/
@Override
protectedvoidondraw (canvas canvas ) {
super.Ondraw(Canvas );
获取SideBar的高度
int viewHeight=getHeight (;
获取SideBar的宽度
int viewWidth=getWidth
();//获得每个字母索引的高度
int singleHeight = viewHeight / alphabet.length;
//绘制每一个字母的索引
for (int i = 0; i < alphabet.length; i++) {
paint.setColor(Color.rgb(34, 66, 99));//设置字母颜色
paint.setTypeface(Typeface.DEFAULT_BOLD);//设置字体
paint.setTextSize(20);//设置字体大小
paint.setAntiAlias(true);//抗锯齿
//如果当前的手指触摸索引和字母索引相同,那么字体颜色进行区分
if (currentChoosenAlphabetIndex == i) {
paint.setColor(Color.parseColor("#3399ff"));
paint.setFakeBoldText(true);
}
/* * 绘制字体,需要制定绘制的x、y轴坐标 * * x轴坐标 = 控件宽度的一半 - 字体宽度的一半 * y轴坐标 = singleHeight * i + singleHeight */
float xpos = viewWidth / 2 - paint.measureText(alphabet[i]) / 2;
float ypos = singleHeight * i + singleHeight;
canvas.drawText(alphabet[i], xpos, ypos, paint);
// 重置画笔,准备绘制下一个字母索引
paint.reset();
}
}
public void setOnLetterTouchedChangeListener(
onLetterTouchedChangeListener onLetterTouchedChangeListener) {
this.onLetterTouchedChangeListener = onLetterTouchedChangeListener;
}
private onLetterTouchedChangeListener getOnLetterTouchedChangeListener() {
return onLetterTouchedChangeListener;
}
/** * 当手指触摸的字母索引发生变化时,调用该回调接口 * *@author owen */
public interface onLetterTouchedChangeListener {
public void onTouchedLetterChange(String letterTouched);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// 触摸事件的代码
final int action = event.getAction();
//手指触摸点在屏幕的Y坐标
final float touchYPos = event.getY();
// 因为currentChoosenAlphabetIndex会不断发生变化,所以用一个变量存储起来
int preChoosenAlphabetIndex = currentChoosenAlphabetIndex;
final onLetterTouchedChangeListener listener = getOnLetterTouchedChangeListener();
// 比例 = 手指触摸点在屏幕的y轴坐标 / SideBar的高度
// 触摸点的索引 = 比例 * 字母索引数组的长度
final int currentTouchIndex = (int) (touchYPos / getHeight() * alphabet.length);
switch (action) {
case MotionEvent.ACTION_UP:
// 如果手指没有触摸屏幕,SideBar的背景颜色为默认,索引字母提示控件不可见
setBackground(new ColorDrawable(0x00000000));
currentChoosenAlphabetIndex = -1;
invalidate();
if (textViewDialog != null) {
textViewDialog.setVisibility(View.INVISIBLE);
}
break;
default:
// 其他情况,比如滑动屏幕、点击屏幕等等,SideBar会改变背景颜色,索引字母提示控件可见,同时需要设置内容
setBackgroundResource(R.drawable.sidebar_background);
// 不是同一个字母索引
if (currentTouchIndex != preChoosenAlphabetIndex) {
// 如果触摸点没有超出控件范围
if (currentTouchIndex >= 0 && currentTouchIndex < alphabet.length) {
if (listener != null) {
listener.onTouchedLetterChange(alphabet[currentTouchIndex]);
}
if (textViewDialog != null) {
textViewDialog.setText(alphabet[currentTouchIndex]);
textViewDialog.setVisibility(View.VISIBLE);
}
currentChoosenAlphabetIndex = currentTouchIndex;
invalidate();
}
}
break;
}
return super.dispatchTouchEvent(event);
}
}
SideBar类就是ListView右侧的字母索引View,我们需要使用setTextView(TextView textViewDialog)来设置用来显示当前按下的字母的TextView,以及使用setOnLetterTouchedChangeListener方法来设置回调接口,在回调方法onLetterTouchedChangeListener(String s)中来处理不同的操作
2.引用SideBar的XML文件(activity_main.xml)
背景自定义
shape是用来定义形状的,gradient定义该形状里面为渐变色填充,startColor起始颜色,endColor结束颜色,angle表示方向角度。当angle=0时,渐变色是从左向右。 然后逆时针方向转,当angle=90时为从下往上
corner是用来定义圆角的,radius为角的弧度,值越大角越圆。
我们还可以把四个角设定成不同的角度,
同时设置五个属性,则Radius属性无效
android:Radius=”20dp” 设置四个角的半径
android:topLeftRadius=”20dp” 设置左上角的半径
android:topRightRadius=”20dp” 设置右上角的半径
android:bottomLeftRadius=”20dp” 设置右下角的半径
android:bottomRightRadius=”20dp” 设置左下角的半径
3.MainActivity的JAVA类文件
package com.example.mysidebar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private SideBar indexBar;
/** * 显示字母的TextView */
private TextView textViewDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
indexBar = (SideBar) findViewById(R.id.sideBar);
textViewDialog = (TextView) findViewById(R.id.textViewDialog);
indexBar.setTextViewDialog(textViewDialog);
}
}
以上就是全部代码了。希望自己能多多练习更加熟练的掌握。