先上设计图
网上找了一些代码 感觉没有办法实现,所以干脆自己手写,使用的是recyclerview +GridLayoutManager
然后右边自己写的自定义LinearLayout 直接上代码 因为我看许多按钮都是写死的26个字母 我想做的是,如果这个字母下没有数据就不显示,所以数据由外面传递过来
public class LetterView extends LinearLayout {
private Context mContext;
private CharacterClickListener mListener;
private List<TextView> textViews = new ArrayList<>();
private int choose = -1;// 选中
public LetterView(Context context) {
super(context);
mContext = context;
setOrientation(VERTICAL);
}
public void setItems(List<String> list) {
for (int i = 0; i < list.size(); i++) {
TextView tv = buildTextLayout(list.get(i));
addView(tv);
}
}
private TextView buildTextLayout(final String str) {
TextView tv = new TextView(mContext);
tv.setPadding(0, AndroidUtilities.dp(1), 0, AndroidUtilities.dp(1));
tv.setGravity(Gravity.CENTER);
tv.setClickable(true);
tv.setTextColor(Theme.TEXT_COLOR_2);
tv.setText(str);
tv.setTextSize(11);
tv.setLayoutParams(LayoutHelper.createLinear(25, LayoutHelper.WRAP_CONTENT));
textViews.add(tv);
return tv;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final float y = event.getY();// 点击y坐标
final int oldChoose = choose;
final int c = (int) (y / getHeight() * textViews.size());// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
choose = -1;
if (mListener != null) {
mListener.onCancel();
}
break;
default:
if (oldChoose != c) {
if (c >= 0 && c < textViews.size()) {
if (mListener != null) {
mListener.clickCharacter(textViews.get(c).getText().toString());
}
choose = c;
}
}
break;
}
return true;
}
public void setCharacterListener(CharacterClickListener listener) {
mListener = listener;
}
public interface CharacterClickListener {
void clickCharacter(String character);
void onCancel();
}
}
然后在activity中使用
RelativeLayout container = new RelativeLayout(context);
container.setPadding(AndroidUtilities.dp(15), 0, AndroidUtilities.dp(0), 0);
recyclerView = new RecyclerView(context);
recyclerView.setHasFixedSize(true);
recyclerView.setPadding(0, 0, AndroidUtilities.dp(25), 0);
gridLayoutManager = new GridLayoutManager(mContext, 3, GridLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new MyItemDecoration());
container.addView(recyclerView, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
letterView = new LetterView(context);
letterView.setCharacterListener(new LetterView.CharacterClickListener() {
@Override
public void clickCharacter(String character) {
if (hintView.getVisibility() == View.GONE) {
textAnimation(true);
}
hintView.setText(character);
if (lettes.containsKey(character)) {
gridLayoutManager.scrollToPositionWithOffset(lettes.get(character), 0);
}
}
@Override
public void onCancel() {
if (hintView.getVisibility() == View.VISIBLE) {
isRunAnimation = false;//保证立即执行隐藏动画
textAnimation(false);
}
}
});
RelativeLayout.LayoutParams letterLP = LayoutHelper.createRelative(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
letterLP.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
letterLP.addRule(RelativeLayout.CENTER_VERTICAL);
container.addView(letterView, letterLP);
adapter = new ScoreFilterAdapter(context);
adapter.setListener(listener);
recyclerView.setAdapter(adapter);
hintView = new TextView(context);
hintView.setTypeface(Theme.fontBold);
hintView.setBackgroundResource(R.drawable.bg_score_filter_text);
hintView.setVisibility(View.GONE);
hintView.setGravity(Gravity.CENTER);
hintView.setTextColor(Color.WHITE);
hintView.setTextSize(24);
container.addView(hintView, LayoutHelper.createRelative(100, 100, RelativeLayout.CENTER_IN_PARENT));
然后上adapter的代码
public class ScoreFilterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private List<ScoreFilterActivity.MatchData> list;
private Map<String, Integer> lettes;
private List<ScoreFilterActivity.MatchData> currSelectList;
public ScoreFilterAdapter(Context context) {
mContext = context;
list = new ArrayList<>();
lettes = new HashMap<>();
currSelectList = new ArrayList<>();
}
public void setList(List<ScoreFilterActivity.MatchData> data, Map<String, Integer> lettes) {
if (data != null && lettes != null) {
this.list.clear();
this.list.addAll(data);
this.lettes.clear();
this.lettes.putAll(lettes);
notifyDataSetChanged();
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case ITEM1:
return new ItemViewHolder(new ScoreFilterCell(mContext), true);
case ITEM2:
return new ItemViewHolder(new ScoreFilterCell(mContext), false);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ScoreFilterActivity.MatchData bean = list.get(position);
((ItemViewHolder) holder).setData(bean);
}
//建立不同布局
public final static int ITEM1 = 101;
public final static int ITEM2 = 102;
@Override
public int getItemViewType(int position) {
//根据每个字母下第一个联系人在数据中的位置,来显示headView
ScoreFilterActivity.MatchData matchData = list.get(position);
if (lettes.get(matchData.getFirstChar()) == position) {
return ITEM1;
} else {
return ITEM2;
}
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if (manager instanceof GridLayoutManager) {
final GridLayoutManager gridManager = ((GridLayoutManager) manager);
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
int type = getItemViewType(position);
switch (type) {
case ITEM1:
return 3;
case ITEM2:
return 1;
default:
return 1;
}
}
});
}
}
@Override
public int getItemCount() {
return list.size();
}
class ItemViewHolder extends RecyclerView.ViewHolder {
private ScoreFilterCell cell;
public ItemViewHolder(ScoreFilterCell cell, boolean isShow) {
super(cell);
this.cell = cell;
this.cell.isShowHead(isShow);
}
public void setData(final ScoreFilterActivity.MatchData data) {
this.cell