最近在做选择城市的列表,需要用到那个字母索引的,觉得这个东西不难就想偷偷懒百度算了,后来找了好几个都感觉写的太复杂了,想想还行自己写一个简单一点的算了,于是就有了下面的字母侧栏索引菜单控件了。
我写的这个很简单,基本都是LinearLayout和TextView,反正就是简单的不能再简单了
有两部分,一个是侧栏控件SidebarView,一个是侧栏子控件SidebarItemView
效果图:
SideBarItemView控件代码:
public class SidebarItemView extends LinearLayout {
private Context mContext;
private LinearLayout vLayout;
private TextView vTitle;
private int screenWidth;
public SidebarItemView(Context context) {
this(context, null, 0);
}
public SidebarItemView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SidebarItemView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mContext = context;
LayoutInflater.from(mContext).inflate(R.layout.wg_sidebar_item, this);
vLayout = (LinearLayout) findViewById(R.id.wg_sidebar_item_root);
vTitle = (TextView) findViewById(R.id.wg_sidebar_item_title);
screenWidth = getScreenWidth();
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(screenWidth / 4, LayoutParams.WRAP_CONTENT);
vLayout.setLayoutParams(lp);
}
/**
* 获取屏幕的宽度(单位:px)
*
* @return 屏幕宽px
*/
public int getScreenWidth() {
WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();// 创建了一张白纸
windowManager.getDefaultDisplay().getMetrics(dm);// 给白纸设置宽高
return dm.widthPixels;
}
/**
* 设置值
*
* @param text
*/
public void setText(String text) {
vTitle.setText(text);
}
/**
* 设置动画
*/
public void setItemAnimation() {
setAnimation(-(screenWidth / 12), -(screenWidth / 12));
}
/**
* 设置动画
*/
public void setItemAnimation2() {
setAnimation(-(screenWidth / 22), -(screenWidth / 22));
}
/**
* 设置动画
* @param fromXDelta
* @param toXDelta
*/
private void setAnimation(float fromXDelta, float toXDelta) {
AnimationSet animationSet = new AnimationSet(true);
final TranslateAnimation animation = new TranslateAnimation(fromXDelta, toXDelta, 0, 0);
animation.setDuration(50);//设置动画持续时间
animation.setFillAfter(false);//动画结束后是否回到原位
animationSet.addAnimation(animation);
vTitle.startAnimation(animation);
animation.startNow();
}
}
SideBarItemView控件布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/wg_sidebar_item_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/wg_sidebar_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-"
android:gravity="center"
android:textColor="#666"
android:layout_gravity="right"
android:layout_marginRight="@dimen/space_8"
android:padding="@dimen/space_4"
android:textSize="@dimen/font_size_22px" />
</LinearLayout>
SidebarView控件代码:
public class SidebarView extends LinearLayout implements View.OnTouchListener {
private Context mContext;
private LinearLayout vLayout;
private TextView vTitle;
public SidebarView(Context context) {
this(context, null, 0);
}
public SidebarView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SidebarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mContext = context;
LayoutInflater.from(mContext).inflate(R.layout.wg_sidebar, this);
vLayout = (LinearLayout) findViewById(R.id.wg_sidebar_layout);
vTitle = (TextView) findViewById(R.id.wg_sidebar_title);
vLayout.setOnTouchListener(this);
List<String> listData = new ArrayList<>();
listData.add("A");
listData.add("B");
listData.add("C");
listData.add("D");
listData.add("E");
listData.add("F");
listData.add("G");
listData.add("H");
listData.add("I");
listData.add("J");
listData.add("K");
listData.add("L");
listData.add("M");
listData.add("N");
listData.add("O");
listData.add("P");
listData.add("Q");
listData.add("R");
listData.add("S");
listData.add("T");
listData.add("U");
listData.add("V");
listData.add("W");
listData.add("X");
listData.add("Y");
listData.add("Z");
setSideDae(listData);
}
/**
* 设置侧栏数据
*
* @param listData
*/
public void setSideDae(List<String> listData) {
vLayout.removeAllViews();
for (String str : listData) {
SidebarItemView tv = new SidebarItemView(mContext);
tv.setTag(str);
tv.setText(str);
vLayout.addView(tv);
}
}
private boolean isDown = false;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
isDown = true;
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
vTitle.setVisibility(View.GONE);
isDown = false;
}
transformValue((LinearLayout) view, motionEvent);
return true;
}
/**
* 转换获取值
*
* @param layout
* @param motionEvent
*/
private void transformValue(LinearLayout layout, MotionEvent motionEvent) {
SidebarItemView textView = (SidebarItemView) layout.getChildAt(0);
float fistViewTop = textView.getTop();
float itemHeight = textView.getMeasuredHeight();
float currentY = motionEvent.getY();
//不超过顶部和顶部
if (motionEvent.getY() > 0 && motionEvent.getY() < layout.getMeasuredHeight()) {
//不超过子控件的范围值
if (currentY > fistViewTop && currentY < (fistViewTop + itemHeight * layout.getChildCount())) {
float rang = currentY - fistViewTop;
int index = (int) (rang / itemHeight);
Log.e("kawa", "rang:" + rang + "_index:" + index + "_itemHeight:" + itemHeight);
vTitle.setText((String) (layout.getChildAt(index).getTag()));
if (listener!=null){
listener.onSelectItem(index,(String) (layout.getChildAt(index).getTag()));
}
if (isDown) {
vTitle.setVisibility(View.VISIBLE);
setAnimation(index, layout);
}
}
}
}
/**
* 设置动画
*
* @param index
* @param layout
*/
private void setAnimation(int index, LinearLayout layout) {
if (index > 1 && index < layout.getChildCount() - 2) {
SidebarItemView tv1 = (SidebarItemView) layout.getChildAt(index - 1);
SidebarItemView tv2 = (SidebarItemView) layout.getChildAt(index);
SidebarItemView tv3 = (SidebarItemView) layout.getChildAt(index + 1);
tv1.setItemAnimation2();
tv2.setItemAnimation();
tv3.setItemAnimation2();
} else {
//第一个的
if (index == 0) {
SidebarItemView tv1 = (SidebarItemView) layout.getChildAt(index);
SidebarItemView tv2 = (SidebarItemView) layout.getChildAt(index + 1);
tv1.setItemAnimation();
tv2.setItemAnimation2();
}
//最后一个的
else {
SidebarItemView tv1 = (SidebarItemView) layout.getChildAt(index);
SidebarItemView tv2 = (SidebarItemView) layout.getChildAt(index - 1);
tv1.setItemAnimation();
tv2.setItemAnimation2();
}
}
}
private OnSidebarViewListener listener;
public void setOnSidebarViewListener(OnSidebarViewListener l) {
listener = l;
}
public interface OnSidebarViewListener {
void onSelectItem(int index, String value);
}
}
SidebarView控件布局文件:
<?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="wrap_content"
android:background="#ffffff"
android:orientation="vertical">
<LinearLayout
android:id="@+id/wg_sidebar_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
<TextView
android:id="@+id/wg_sidebar_title"
android:layout_width="@dimen/space_120"
android:layout_height="@dimen/space_120"
android:layout_centerInParent="true"
android:gravity="center"
android:text="-"
android:textSize="@dimen/font_size_30px"
android:textColor="#fff"
android:visibility="gone"
android:background="#666"
android:padding="@dimen/space_24"/>
</RelativeLayout>
用法,将你的控件引入到需要的页面就行
<com.kawa.qkplug.widget.SidebarView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
上面只是粗略写了一下,具体样式自己根据实际情况改改就行了