具有选择效果的flexablelayout
最近项目用到标签选择效果,类似
不同的是,要带有选中效果,即,点击选中,并回调选中项。 有人可能会问,为什么不说那个FlexBoxLayoutManager + RecyclerView实现点击选中等效果呢?
是因为目前FlexBoxLayoutManager存在问题,在布局的时候回出现位置计算不准确的问题,详情见
回调代码如下:
public interface OnSelectChangedListener {
void onItemSelected(int position, View view);
}
final String[] labels = new String[]{"程序员", "影视天堂", "美食", "漫画.手绘", "广告图", "旅行.在路上","娱乐八卦", "青春", "谈写作", "短篇小说", "散文", "摄影"};
houseFlexboxlayoutVideolabels.setData(labels);
houseFlexboxlayoutVideolabels.setOnSelectChangedListener(new SelectableFlexboxLayout.OnSelectChangedListener() {
@Override
public void onItemSelected(int position, View view) {
Toast.makeText(getApplication(),labels[position], Toast.LENGTH_LONG).show;
}
});
下面直接将封装代码奉上,有问题可以留言联系哈。
selectable_flexboxlayout_container.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:link="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/house_video_label_flexbox_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.google.android.flexbox.FlexboxLayout>
label_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/tv_video_label"
android:layout_width="wrap_content"
android:layout_height="@dimen/dimen_32dp"
android:paddingLeft="@dimen/margin_12"
android:paddingRight="@dimen/margin_12"
android:gravity="center"
android:textSize="@dimen/textsize_13"
android:textColor="@color/color_4a4e59"
android:background="@drawable/selector_bg_label" />
点击效果 selector_bg_label.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/label_selected" android:state_selected="true" />
<item android:drawable="@drawable/label_selected"
android:state_checked="true" />
<item android:drawable="@drawable/label_normal" />
</selector>
label_selected,label_normal即为自己实现的选中效果
public class SelectableFlexboxLayout extends FlexboxLayout implements View.OnClickListener {
private FlexboxLayout container;
private LayoutInflater inflater;
private ViewHolder mSelectedItem;
private OnSelectChangedListener mOnSelectChangedListener;
private List<ViewHolder> holders = new ArrayList<>();
public SelectableFlexboxLayout(Context context) {
super(context);
}
public SelectableFlexboxLayout(Context context, AttributeSet attrs) {
super(context, attrs);
inflater = LayoutInflater.from(getContext());
inflate(context, R.layout.selectable_flexboxlayout_container, this);
container = (FlexboxLayout)findViewById(R.id.house_video_label_flexbox_container);
container.setFlexWrap(FLEX_WRAP_WRAP);
container.setAlignItems(ALIGN_ITEMS_FLEX_START);
container.setDividerDrawable(getResources().getDrawable(R.drawable.house_video_label_divider_placeholder));
container.setShowDivider(SHOW_DIVIDER_MIDDLE);
}
public SelectableFlexboxLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void addItems(CharSequence[] titles, int initSelected) {
if (titles == null || titles.length == 0) return;
for (int i = 0; i < titles.length; i++) {
View item = inflater.inflate(R.layout.label_item, container, false);
ViewHolder holder = new ViewHolder(item, i, titles[i]);
item.setTag(holder);
item.setOnClickListener(this);
holders.add(holder);
if (i == initSelected) {
mSelectedItem = holder;
holder.setItemStatus(true);
} else {
holder.setItemStatus(false);
}
container.addView(item);
}
}
@Override public void onClick(View v) {
ViewHolder holder = (ViewHolder) v.getTag();
if (holder == mSelectedItem) return;
mSelectedItem.setItemStatus(false);
mSelectedItem = holder;
holder.setItemStatus(true);
if (mOnSelectChangedListener != null) {
mOnSelectChangedListener.onItemSelected(holder.mPosition, v);
}
}
public static class ViewHolder {
private Context context;
private View mRoot;
private TextView mTitle;
private int mPosition;
ViewHolder(final View root, int position, CharSequence title) {
this.context = root.getContext();
mRoot = root;
mTitle = (TextView) root.findViewById(R.id.tv_video_label);
mTitle.setText(title);
mPosition = position;
}
public void setItemStatus(boolean isSelected) {
mTitle.setTextColor(isSelected ? Color.WHITE : ContextCompat.getColor(context, R.color.color_4A4E59));
mRoot.setSelected(isSelected);
}
}
public void setOnSelectChangedListener(OnSelectChangedListener listener) {
mOnSelectChangedListener = listener;
}
public void setSelectPosition(int position) {
if (mSelectedItem != null && mSelectedItem.mPosition == position) return;
if (position >= this.getChildCount()) return;
View view = this.getChildAt(position);
if (view != null) {
mSelectedItem.setItemStatus(false);
mSelectedItem = (ViewHolder) view.getTag();
mSelectedItem.setItemStatus(true);
}
}
public void setData(String[] titles) {
setData(titles, 0);
}
public void setData(String[] titles, int initIndex) {
addItems(titles, initIndex);
}
public List<ViewHolder> getViewHolders() {
return holders != null ? Collections.unmodifiableList(holders)
: Collections.<ViewHolder>emptyList();
}
public interface OnSelectChangedListener {
void onItemSelected(int position, View view);
}
}
如有缺漏不足之处,欢迎创建issue,PR 😄