Comments (26)
所以传递 null导致的结果就是
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
from indexablerecyclerview.
singerHeaderAdapter.addDatas(mRecommendSingers);
singerHeaderAdapter.notifyDataSetChanged(); 我加了非空判断,这样还是没有数据。。
from indexablerecyclerview.
我尝试第一次初始化,在网格布局graidlayout, 中 头部区域 显示的是空白。
from indexablerecyclerview.
而且头部区域无法滚动上去只能通过右边定位
from indexablerecyclerview.
再说一次 grid的方式头部无法正常使用。。。而且那个区域滚动不上去。
from indexablerecyclerview.
使用NestedScrollView 嵌套 右边索引又没有了。
from indexablerecyclerview.
改了 一下 设置管理器功能可是又有地方出问题了
if (nextTitleView!=null &&nextTitleView.getTop() <= mStickyViewHolder.itemView.getHeight() && wrapperTitle != null) {
mStickyViewHolder.itemView.setTranslationY(nextTitleView.getTop() - mStickyViewHolder.itemView.getHeight());
}
if (INVISIBLE == nextTitleView.getVisibility()) {
//特殊情况:手指向下滑动的时候,需要及时把成为第二个可见View的TitleView设置Visible,
// 这样才能配合StickyView制造两个TitleView切换的动画。
nextTit
空指针 。
from indexablerecyclerview.
而且头部是竖排。
from indexablerecyclerview.
大神啥时候在线呀,我得技术太烂不知道咋修复
from indexablerecyclerview.
这次更新顺便加上一个功能吧,就是右边覆盖层问题,已经置顶的,我这里也弄了。
from indexablerecyclerview.
另外建议弄个关键字的头部 既然不支持我就打算另辟蹊径 比如 置顶叫★, 其他的列为 #最后面
from indexablerecyclerview.
头部问题: 先让页面显示一个loading, 然后网络数据返回时,再初始化RecyclerView ,头部这块 视觉上就是正常的了
from indexablerecyclerview.
现在的问题是头部不支持grid,,所以我现在在写★索引。
from indexablerecyclerview.
如果你头部的Grid的条目不多的话,建议自定义一个View,负责装载这些条目;
如果Grid真是复杂而且动态性很大,建议自己fork下代码改造
from indexablerecyclerview.
只是基于gridview加一个头部而已 结果不行
from indexablerecyclerview.
空白
from indexablerecyclerview.
各种改都没搞定 不会改
from indexablerecyclerview.
现在改成★作为索引顶部结果出现了重复的索引五角星
from indexablerecyclerview.
哦哦, GridView是小伙伴提的PR, 头部兼容性上次我看了好像没问题
最近个人非常忙,可以不能及时维护.. 暂时可以自己改造下~
from indexablerecyclerview.
空白,改了下合并了终于显示头部了但是是单列,而且 有地方结果空指针 判断空指针返回结果所有头部没有了,问题也U来越多 不清楚整个代码没法继续了
from indexablerecyclerview.
上次issue说,这个库的目标是 比较大众的需求, 你的需求挺特殊,拿这个库改的话,一些不熟悉的地方会踩坑,建议自己写一套,可维护性更高
from indexablerecyclerview.
你的需求github上应该找不到对应的库,都需要自己修改,可以考虑研究一波,自己定制一个
from indexablerecyclerview.
--没想到这需求挑战项目极限了,希望
![Uploading image.pn您老弄得越来越完善
from indexablerecyclerview.
我现在的解决方法只有这样了,要置顶的item,排序里面添加索引五角星 ,添加头标记索引 排序返回最大,
public int compare(String lhs, String rhs) {
int result;
if (lhs.equals(INDEX_START_SIGN)) {
if(lhs.equals(rhs)){
return 0;
}
result = 300;
} else if (rhs.equals(INDEX_START_SIGN)) {
result = 300;
}
else
if (lhs.equals(INDEX_END_SIGN)) {
result = rhs.equals(INDEX_END_SIGN) ? 0 : 1;
} else if (rhs.equals(INDEX_END_SIGN)) {
result = -1;
} else {
result = lhs.compareTo(rhs);
}
/*
if (lhs.equals(INDEX_START_SIGN)) {
return rhs.equals(INDEX_START_SIGN) ? 1 : 1;
} else if (lhs.equals(INDEX_START_SIGN)) {
return rhs.equals(INDEX_START_SIGN) ? 1 : 1;
} else if (lhs.equals(INDEX_END_SIGN)) {
return rhs.equals(INDEX_END_SIGN) ? 0 : 1;
} else if (rhs.equals(INDEX_END_SIGN)) {
return -1;
}
*/
if (lhs.equals(INDEX_START_SIGN) || rhs.startsWith(INDEX_START_SIGN)) {
Log.w(TAG, "Sort_left:" + lhs + ",rls:" + rhs + ",RESULT:" + result);
}
return result;
if (indexName.startsWith(INDEX_START_SIGN)) {
entity.setIndex(INDEX_START_SIGN);
entity.setPinyin(INDEX_START_SIGN);
entity.setIndexByField(item.getFieldIndexBy());
} else if (PinyinUtil.match
from indexablerecyclerview.
最后感谢,达到了置顶需求就可以了,在a-z之外的 五角星排序主要是标题不雅观需要在适配器里面处理一下包含五角星了。
from indexablerecyclerview.
解决了置顶变色,已经置顶某些单独的item作为★排序。
解决方法就是在indexbar加上一个标签显示
void setDatas(boolean showAllLetter, ArrayList<EntityWrapper> datas) {
this.mDatas = datas;
this.mIndexList.clear();
this.mMapping.clear();
ArrayList<String> tempHeaderList = null;
if (showAllLetter) {
mIndexList = Arrays.asList(getResources().getStringArray(R.array.indexable_letter));
mIndexList = new ArrayList<>(mIndexList);
tempHeaderList = new ArrayList<>();
}
for (int i = 0; i < datas.size(); i++) {
EntityWrapper wrapper = datas.get(i);
if (wrapper.getItemType() == EntityWrapper.TYPE_TITLE || wrapper.getIndexTitle() == null) {
String index = wrapper.getIndex();
if (!TextUtils.isEmpty(index)) {
if (!showAllLetter) {
mIndexList.add(index);
} else {
if (IndexableLayout.INDEX_END_SIGN.equals(index)) {
mIndexList.add(IndexableLayout.INDEX_END_SIGN);
}
**if (IndexableLayout.INDEX_START_SIGN.equals(index)) {
mIndexList.add(0, IndexableLayout.INDEX_START_SIGN);
}** else if (mIndexList.indexOf(index) < 0) {
if (wrapper.getHeaderFooterType() == EntityWrapper.TYPE_HEADER && tempHeaderList.indexOf(index) < 0) {
tempHeaderList.add(index);
} else if (wrapper.getHeaderFooterType() == EntityWrapper.TYPE_FOOTER) {
mIndexList.add(index);
}
}
}
if (!mMapping.containsKey(index)) {
mMapping.put(index, i);
}
}
}
}
if (showAllLetter) {
mIndexList.addAll(0, tempHeaderList);
}
requestLayout();
}
贴上IndexableLayout 源码
`
package me.yokeyword.indexablerv;
import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.IntDef;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import me.yokeyword.indexablerecyclerview.R;
import me.yokeyword.indexablerv.database.DataObserver;
import me.yokeyword.indexablerv.database.HeaderFooterDataObserver;
import me.yokeyword.indexablerv.database.IndexBarDataObserver;
/**
* RecyclerView + IndexBar
* Created by YoKey on 16/10/6.
*/
@SuppressWarnings("unchecked")
public class IndexableLayout extends FrameLayout {
public static final String TAG = "IndexableLayout";
// 快速排序,只比对首字母(默认)
public static final int MODE_FAST = 0;
// 全字母比较排序, 效率最低
public static final int MODE_ALL_LETTERS = 1;
// 每个字母模块内:无需排序,效率最高
public static final int MODE_NONE = 2;
private static int PADDING_RIGHT_OVERLAY;
public static final String INDEX_END_SIGN = "#";
public static final String INDEX_START_SIGN = "★";
private Context mContext;
private boolean mShowAllLetter = true;
private ExecutorService mExecutorService;
private Future mFuture;
private RecyclerView mRecy;
private IndexBar mIndexBar;
/**
* 保存正在Invisible的ItemView
* <p>
* 使用mLastInvisibleRecyclerViewItemView来保存当前Invisible的ItemView,
* 每次有新的ItemView需要Invisible的时候,把旧的Invisible的ItemView设为Visible。
* 这样就修复了View复用导致的Invisible状态传递的问题。
*/
private View mLastInvisibleRecyclerViewItemView;
private boolean mSticyEnable = true;
private RecyclerView.ViewHolder mStickyViewHolder;
private String mStickyTitle;
private RealAdapter mRealAdapter;
private LinearLayoutManager mLinearLayoutManager;
private GridLayoutManager mGridLayoutManager;
private IndexableAdapter mIndexableAdapter;
private TextView mCenterOverlay, mMDOverlay;
private int mBarTextColor, mBarFocusTextColor;
private float mBarTextSize, mBarTextSpace, mBarWidth;
private Drawable mBarBg;
private DataObserver mDataSetObserver;
private int mCompareMode = MODE_FAST;
private Handler mHandler;
private HeaderFooterDataObserver<EntityWrapper> mHeaderFooterDataSetObserver = new HeaderFooterDataObserver<EntityWrapper>() {
@Override
public void onChanged() {
if (mRealAdapter == null) return;
mRealAdapter.notifyDataSetChanged();
}
@Override
public void onAdd(boolean header, EntityWrapper preData, EntityWrapper data) {
if (mRealAdapter == null) return;
mRealAdapter.addHeaderFooterData(header, preData, data);
}
@Override
public void onRemove(boolean header, EntityWrapper data) {
if (mRealAdapter == null) return;
mRealAdapter.removeHeaderFooterData(header, data);
}
};
private IndexBarDataObserver mIndexBarDataSetObserver = new IndexBarDataObserver() {
@Override
public void onChanged() {
mIndexBar.setDatas(mShowAllLetter, mRealAdapter.getItems());
}
};
public IndexableLayout(Context context) {
this(context, null);
}
public IndexableLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public IndexableLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
/**
* set RealAdapter
* {@link #setLayoutManager(RecyclerView.LayoutManager)}
*/
public <T extends IndexableEntity> void setAdapter(final IndexableAdapter<T> adapter) {
if (mGridLayoutManager == null && mLinearLayoutManager == null) {
throw new NullPointerException("U should set the LayoutManager first");
}
this.mIndexableAdapter = adapter;
if (mDataSetObserver != null) {
adapter.unregisterDataSetObserver(mDataSetObserver);
}
mDataSetObserver = new DataObserver() {
@Override
public void onInited() {
onSetListener(IndexableAdapter.TYPE_ALL);
onDataChanged();
}
@Override
public void onChanged() {
if (mRealAdapter != null) {
mRealAdapter.notifyDataSetChanged();
}
}
@Override
public void onSetListener(int type) {
// set listeners
if ((type == IndexableAdapter.TYPE_CLICK_TITLE || type == IndexableAdapter.TYPE_ALL) && adapter.getOnItemTitleClickListener() != null) {
mRealAdapter.setOnItemTitleClickListener(adapter.getOnItemTitleClickListener());
}
if ((type == IndexableAdapter.TYPE_LONG_CLICK_TITLE || type == IndexableAdapter.TYPE_ALL) && adapter.getOnItemTitleLongClickListener() != null) {
mRealAdapter.setOnItemTitleLongClickListener(adapter.getOnItemTitleLongClickListener());
}
if ((type == IndexableAdapter.TYPE_CLICK_CONTENT || type == IndexableAdapter.TYPE_ALL) && adapter.getOnItemContentClickListener() != null) {
mRealAdapter.setOnItemContentClickListener(adapter.getOnItemContentClickListener());
}
if ((type == IndexableAdapter.TYPE_LONG_CLICK_CONTENT || type == IndexableAdapter.TYPE_ALL) && adapter.getOnItemContentLongClickListener() != null) {
mRealAdapter.setOnItemContentLongClickListener(adapter.getOnItemContentLongClickListener());
}
}
};
adapter.registerDataSetObserver(mDataSetObserver);
mRealAdapter.setIndexableAdapter(adapter);
if (mSticyEnable) {
initStickyView(adapter);
}
}
/**
* add HeaderView Adapter
*/
public <T> void addHeaderAdapter(IndexableHeaderAdapter<T> adapter) {
adapter.registerDataSetObserver(mHeaderFooterDataSetObserver);
adapter.registerIndexBarDataSetObserver(mIndexBarDataSetObserver);
mRealAdapter.addIndexableHeaderAdapter(adapter);
}
/**
* removeData HeaderView Adapter
*/
public <T> void removeHeaderAdapter(IndexableHeaderAdapter<T> adapter) {
try {
adapter.unregisterDataSetObserver(mHeaderFooterDataSetObserver);
adapter.unregisterIndexBarDataSetObserver(mIndexBarDataSetObserver);
mRealAdapter.removeIndexableHeaderAdapter(adapter);
} catch (Exception ignored) {
}
}
/**
* add FooterView Adapter
*/
public <T> void addFooterAdapter(IndexableFooterAdapter<T> adapter) {
adapter.registerDataSetObserver(mHeaderFooterDataSetObserver);
adapter.registerIndexBarDataSetObserver(mIndexBarDataSetObserver);
mRealAdapter.addIndexableFooterAdapter(adapter);
}
/**
* removeData FooterView Adapter
*/
public <T> void removeFooterAdapter(IndexableFooterAdapter<T> adapter) {
try {
adapter.unregisterDataSetObserver(mHeaderFooterDataSetObserver);
adapter.unregisterIndexBarDataSetObserver(mIndexBarDataSetObserver);
mRealAdapter.removeIndexableFooterAdapter(adapter);
} catch (Exception ignored) {
}
}
/**
* set sort-mode
* Deprecated {@link #setCompareMode(int)}
*/
@Deprecated
public void setFastCompare(boolean fastCompare) {
setCompareMode(fastCompare ? MODE_FAST : MODE_ALL_LETTERS);
}
@IntDef({MODE_FAST, MODE_ALL_LETTERS, MODE_NONE})
@Retention(RetentionPolicy.SOURCE)
@interface CompareMode {
}
/**
* set sort-mode
*/
public void setCompareMode(@CompareMode int mode) {
this.mCompareMode = mode;
}
/**
* set Sticky Enable
*/
public void setStickyEnable(boolean enable) {
this.mSticyEnable = enable;
}
/**
* display all letter-index
*/
public void showAllLetter(boolean show) {
mShowAllLetter = show;
}
/**
* display Material Design OverlayView
*/
public void setOverlayStyle_MaterialDesign(int color) {
if (mMDOverlay == null) {
initMDOverlay(color);
} else {
ViewCompat.setBackgroundTintList(mMDOverlay, ColorStateList.valueOf(color));
}
mCenterOverlay = null;
}
/**
* display Center OverlayView
*/
public void setOverlayStyle_Center() {
if (mCenterOverlay == null) {
initCenterOverlay();
}
mMDOverlay = null;
}
/**
* get OverlayView
*/
public TextView getOverlayView() {
return mMDOverlay != null ? mMDOverlay : mCenterOverlay;
}
/**
* get RecyclerView
*/
public RecyclerView getRecyclerView() {
return mRecy;
}
/**
* Set the enabled state of this IndexBar.
*/
public void setIndexBarVisibility(boolean visible) {
mIndexBar.setVisibility(visible ? VISIBLE : GONE);
}
private void init(Context context, AttributeSet attrs) {
this.mContext = context;
this.mExecutorService = Executors.newSingleThreadExecutor();
PADDING_RIGHT_OVERLAY = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, getResources().getDisplayMetrics());
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IndexableRecyclerView);
mBarTextColor = a.getColor(R.styleable.IndexableRecyclerView_indexBar_textColor, ContextCompat.getColor(context, R.color.default_indexBar_textColor));
mBarTextSize = a.getDimension(R.styleable.IndexableRecyclerView_indexBar_textSize, getResources().getDimension(R.dimen.default_indexBar_textSize));
mBarFocusTextColor = a.getColor(R.styleable.IndexableRecyclerView_indexBar_selectedTextColor, ContextCompat.getColor(context, R.color.default_indexBar_selectedTextColor));
mBarTextSpace = a.getDimension(R.styleable.IndexableRecyclerView_indexBar_textSpace, getResources().getDimension(R.dimen.default_indexBar_textSpace));
mBarBg = a.getDrawable(R.styleable.IndexableRecyclerView_indexBar_background);
mBarWidth = a.getDimension(R.styleable.IndexableRecyclerView_indexBar_layout_width, getResources().getDimension(R.dimen.default_indexBar_layout_width));
a.recycle();
}
if (mContext instanceof Activity) {
((Activity) mContext).getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
}
mRecy = new RecyclerView(context);
mRecy.setVerticalScrollBarEnabled(false);
mRecy.setOverScrollMode(View.OVER_SCROLL_NEVER);
LayoutParams params1 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mRecy.setPadding(0, 0, (int) mBarWidth, 0);//右边
addView(mRecy, params1);
mIndexBar = new IndexBar(context);
mIndexBar.init(mBarBg, mBarTextColor, mBarFocusTextColor, mBarTextSize, mBarTextSpace);
LayoutParams params = new LayoutParams((int) mBarWidth, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.END | Gravity.CENTER_VERTICAL;
addView(mIndexBar, params);
mRealAdapter = new RealAdapter();
mRecy.setHasFixedSize(true);
mRecy.setAdapter(mRealAdapter);
initListener();
}
/**
* {@link #setAdapter(IndexableAdapter)}
*
* @param layoutManager One of LinearLayoutManager and GridLayoutManager
*/
public void setLayoutManager(RecyclerView.LayoutManager layoutManager) {
if (layoutManager instanceof GridLayoutManager) {
mGridLayoutManager = (GridLayoutManager) layoutManager;
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
int spanSize = 0;
if (mRealAdapter.getItemViewType(position) == EntityWrapper.TYPE_TITLE) {
spanSize = mGridLayoutManager.getSpanCount();
} else if (mRealAdapter.getItemViewType(position) == EntityWrapper.TYPE_CONTENT) {
spanSize = 1;
}
return spanSize;
}
});
mRecy.setLayoutManager(mGridLayoutManager);
} else if (layoutManager instanceof LinearLayoutManager) {
mLinearLayoutManager = (LinearLayoutManager) layoutManager;
mRecy.setLayoutManager(mLinearLayoutManager);
}
}
private void initListener() {
mRecy.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstItemPosition = 0;
if (mLinearLayoutManager != null) {
firstItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition();
} else if (mGridLayoutManager != null) {
firstItemPosition = mGridLayoutManager.findFirstVisibleItemPosition();
}
mIndexBar.setSelection(firstItemPosition);
if (!mSticyEnable) return;
ArrayList<EntityWrapper> list = mRealAdapter.getItems();
if (mStickyViewHolder != null && list.size() > firstItemPosition) {
EntityWrapper wrapper = list.get(firstItemPosition);
String wrapperTitle = wrapper.getIndexTitle();
if (EntityWrapper.TYPE_TITLE == wrapper.getItemType()) {
if (mLastInvisibleRecyclerViewItemView != null && mLastInvisibleRecyclerViewItemView.getVisibility() == INVISIBLE) {
mLastInvisibleRecyclerViewItemView.setVisibility(VISIBLE);
mLastInvisibleRecyclerViewItemView = null;
}
if (mLinearLayoutManager != null) {
mLastInvisibleRecyclerViewItemView = mLinearLayoutManager.findViewByPosition(firstItemPosition);
} else if (mGridLayoutManager != null) {
mLastInvisibleRecyclerViewItemView = mGridLayoutManager.findViewByPosition(firstItemPosition);
}
if (mLastInvisibleRecyclerViewItemView != null) {
mLastInvisibleRecyclerViewItemView.setVisibility(INVISIBLE);
}
}
// hide -> show
if (wrapperTitle == null && mStickyViewHolder.itemView.getVisibility() == VISIBLE) {
mStickyTitle = null;
mStickyViewHolder.itemView.setVisibility(INVISIBLE);
} else {
stickyNewViewHolder(wrapperTitle);
}
// LinearLayoutManager
if (mLinearLayoutManager != null) {
if (firstItemPosition + 1 < list.size()) {
EntityWrapper nextWrapper = list.get(firstItemPosition + 1);
View nextTitleView = mLinearLayoutManager.findViewByPosition(firstItemPosition + 1);
if (nextWrapper.getItemType() == EntityWrapper.TYPE_TITLE) {
if (nextTitleView.getTop() <= mStickyViewHolder.itemView.getHeight() && wrapperTitle != null) {
mStickyViewHolder.itemView.setTranslationY(nextTitleView.getTop() - mStickyViewHolder.itemView.getHeight());
}
if (INVISIBLE == nextTitleView.getVisibility()) {
//特殊情况:手指向下滑动的时候,需要及时把成为第二个可见View的TitleView设置Visible,
// 这样才能配合StickyView制造两个TitleView切换的动画。
nextTitleView.setVisibility(VISIBLE);
}
} else if (mStickyViewHolder.itemView.getTranslationY() != 0) {
mStickyViewHolder.itemView.setTranslationY(0);
}
}
}
// GirdLayoutManager
if (mGridLayoutManager != null) {
if (firstItemPosition + mGridLayoutManager.getSpanCount() < list.size()) {
for (int i = firstItemPosition + 1; i <= firstItemPosition + mGridLayoutManager.getSpanCount(); i++) {
EntityWrapper nextWrapper = list.get(i);
View nextTitleView = mGridLayoutManager.findViewByPosition(i);
if (nextWrapper.getItemType() == EntityWrapper.TYPE_TITLE) {
if (nextTitleView.getTop() <= mStickyViewHolder.itemView.getHeight() && wrapperTitle != null) {
mStickyViewHolder.itemView.setTranslationY(nextTitleView.getTop() - mStickyViewHolder.itemView.getHeight());
}
if (INVISIBLE == nextTitleView.getVisibility()) {
//特殊情况:手指向下滑动的时候,需要及时把成为第二个可见View的TitleView设置Visible,
// 这样才能配合StickyView制造两个TitleView切换的动画。
nextTitleView.setVisibility(VISIBLE);
}
break;
} else if (mStickyViewHolder.itemView.getTranslationY() != 0) {
mStickyViewHolder.itemView.setTranslationY(0);
}
}
}
} // end GridLayoutManager
}
}
});
mIndexBar.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int touchPos = mIndexBar.getPositionForPointY(event.getY());
if (touchPos < 0) return true;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
showOverlayView(event.getY(), touchPos);
if (touchPos != mIndexBar.getSelectionPosition()) {
mIndexBar.setSelectionPosition(touchPos);
if (touchPos == 0) {
if (mLinearLayoutManager != null) {
mLinearLayoutManager.scrollToPositionWithOffset(0, 0);
} else if (mGridLayoutManager != null) {
mGridLayoutManager.scrollToPositionWithOffset(0, 0);
}
} else {
if (mLinearLayoutManager != null) {
mLinearLayoutManager.scrollToPositionWithOffset(mIndexBar.getFirstRecyclerViewPositionBySelection(), 0);
} else if (mGridLayoutManager != null) {
mGridLayoutManager.scrollToPositionWithOffset(mIndexBar.getFirstRecyclerViewPositionBySelection(), 0);
}
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (mCenterOverlay != null) mCenterOverlay.setVisibility(GONE);
if (mMDOverlay != null) mMDOverlay.setVisibility(GONE);
break;
}
return true;
}
});
}
private void stickyNewViewHolder(String wrapperTitle) {
if ((wrapperTitle != null && !wrapperTitle.equals(mStickyTitle))) {
if (mStickyViewHolder.itemView.getVisibility() != VISIBLE) {
mStickyViewHolder.itemView.setVisibility(VISIBLE);
}
mStickyTitle = wrapperTitle;
mIndexableAdapter.onBindTitleViewHolder(mStickyViewHolder, wrapperTitle);
}
}
private <T extends IndexableEntity> void initStickyView(final IndexableAdapter<T> adapter) {
mStickyViewHolder = adapter.onCreateStickyTitleViewHolder(mRecy);
mStickyViewHolder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (adapter.getOnItemTitleClickListener() != null) {
int position = mIndexBar.getFirstRecyclerViewPositionBySelection();
ArrayList<EntityWrapper> datas = mRealAdapter.getItems();
if (datas.size() > position && position >= 0) {
adapter.getOnItemTitleClickListener().onItemClick(
v, position, datas.get(position).getIndexTitle());
}
}
}
});
mStickyViewHolder.itemView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (adapter.getOnItemTitleLongClickListener() != null) {
int position = mIndexBar.getFirstRecyclerViewPositionBySelection();
ArrayList<EntityWrapper> datas = mRealAdapter.getItems();
if (datas.size() > position && position >= 0) {
return adapter.getOnItemTitleLongClickListener().onItemLongClick(
v, position, datas.get(position).getIndexTitle());
}
}
return false;
}
});
for (int i = 0; i < getChildCount(); i++) {
if (getChildAt(i) == mRecy) {
mStickyViewHolder.itemView.setVisibility(INVISIBLE);
// mStickyViewHolder.itemView.setBackgroundColor(Color.RED);
addView(mStickyViewHolder.itemView, i + 1);
return;
}
}
}
private void showOverlayView(float y, final int touchPos) {
if (mIndexBar.getIndexList().size() <= touchPos) return;
if (mMDOverlay != null) {
if (mMDOverlay.getVisibility() != VISIBLE) {
mMDOverlay.setVisibility(VISIBLE);
}
if (y < PADDING_RIGHT_OVERLAY - mIndexBar.getTop() && y >= 0) {
y = PADDING_RIGHT_OVERLAY - mIndexBar.getTop();
} else if (y < 0) {
if (mIndexBar.getTop() > PADDING_RIGHT_OVERLAY) {
y = 0;
} else {
y = PADDING_RIGHT_OVERLAY - mIndexBar.getTop();
}
} else if (y > mIndexBar.getHeight()) {
y = mIndexBar.getHeight();
}
mMDOverlay.setY(mIndexBar.getTop() + y - PADDING_RIGHT_OVERLAY);
String index = mIndexBar.getIndexList().get(touchPos);
if (!mMDOverlay.getText().equals(index)) {
if (index.length() > 1) {
mMDOverlay.setTextSize(30);
}
mMDOverlay.setText(index);
}
}
if (mCenterOverlay != null) {
if (mCenterOverlay.getVisibility() != VISIBLE) {
mCenterOverlay.setVisibility(VISIBLE);
}
String index = mIndexBar.getIndexList().get(touchPos);
if (!mCenterOverlay.getText().equals(index)) {
if (index.length() > 1) {
mCenterOverlay.setTextSize(32);
}
mCenterOverlay.setText(index);
}
}
}
private void initCenterOverlay() {
mCenterOverlay = new TextView(mContext);
mCenterOverlay.setBackgroundResource(R.drawable.indexable_bg_center_overlay);
mCenterOverlay.setTextColor(Color.WHITE);
mCenterOverlay.setTextSize(40);
mCenterOverlay.setGravity(Gravity.CENTER);
int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 70, getResources().getDisplayMetrics());
LayoutParams params = new LayoutParams(size, size);
params.gravity = Gravity.CENTER;
mCenterOverlay.setLayoutParams(params);
mCenterOverlay.setVisibility(INVISIBLE);
addView(mCenterOverlay);
}
private void initMDOverlay(int color) {
mMDOverlay = new AppCompatTextView(mContext);
mMDOverlay.setBackgroundResource(R.drawable.indexable_bg_md_overlay);
((AppCompatTextView) mMDOverlay).setSupportBackgroundTintList(ColorStateList.valueOf(color));
mMDOverlay.setSingleLine();
mMDOverlay.setTextColor(Color.WHITE);
mMDOverlay.setTextSize(38);
mMDOverlay.setGravity(Gravity.CENTER);
int size = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 72, getResources().getDisplayMetrics());
LayoutParams params = new LayoutParams(size, size);
params.rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 33, getResources().getDisplayMetrics());
params.gravity = Gravity.END;
mMDOverlay.setLayoutParams(params);
mMDOverlay.setVisibility(INVISIBLE);
addView(mMDOverlay);
}
void onDataChanged() {
if (mFuture != null) {
mFuture.cancel(true);
}
mFuture = mExecutorService.submit(new Runnable() {
@Override
public void run() {
final ArrayList<EntityWrapper> datas = transform(mIndexableAdapter.getItems());
if (datas == null) return;
getSafeHandler().post(new Runnable() {
@Override
public void run() {
mRealAdapter.setDatas(datas);
mIndexBar.setDatas(mShowAllLetter, mRealAdapter.getItems());
if (mIndexableAdapter.getIndexCallback() != null) {
mIndexableAdapter.getIndexCallback().onFinished(datas);
}
}
});
}
});
}
/**
* List<T> -> List<Indexable<T>
*/
private <T extends IndexableEntity> ArrayList<EntityWrapper<T>> transform(final List<T> datas) {
try {
TreeMap<String, List<EntityWrapper<T>>> map = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String lhs, String rhs) {
int result;
if (lhs.equals(INDEX_START_SIGN)) {
if (lhs.equals(rhs)) {
return 0;
}
result = 300;
} else if (rhs.equals(INDEX_START_SIGN)) {
result = 300;
} else if (lhs.equals(INDEX_END_SIGN)) {
result = rhs.equals(INDEX_END_SIGN) ? 0 : 1;
} else if (rhs.equals(INDEX_END_SIGN)) {
result = -1;
} else {
result = lhs.compareTo(rhs);
}
/*
if (lhs.equals(INDEX_START_SIGN)) {
return rhs.equals(INDEX_START_SIGN) ? 1 : 1;
} else if (lhs.equals(INDEX_START_SIGN)) {
return rhs.equals(INDEX_START_SIGN) ? 1 : 1;
} else if (lhs.equals(INDEX_END_SIGN)) {
return rhs.equals(INDEX_END_SIGN) ? 0 : 1;
} else if (rhs.equals(INDEX_END_SIGN)) {
return -1;
}
*/
if (lhs.equals(INDEX_START_SIGN) || rhs.startsWith(INDEX_START_SIGN)) {
Log.w(TAG, "Sort_left:" + lhs + ",rls:" + rhs + ",RESULT:" + result);
}
return result;
}
});
for (int i = 0; i < datas.size(); i++) {
EntityWrapper<T> entity = new EntityWrapper<>();
T item = datas.get(i);
String indexName = item.getFieldIndexBy();
String pinyin = PinyinUtil.getPingYin(indexName);
// init EntityWrapper
if (indexName.startsWith(INDEX_START_SIGN)) {
entity.setIndex(INDEX_START_SIGN);
entity.setPinyin(INDEX_START_SIGN);
String doWhile = indexName;
doWhile = doWhile.replace(IndexableLayout.INDEX_START_SIGN, "");
entity.setIndexByField(doWhile);
} else if (PinyinUtil.matchingLetter(pinyin)) {
entity.setIndex(pinyin.substring(0, 1).toUpperCase());
entity.setPinyin(pinyin);
entity.setIndexByField(item.getFieldIndexBy());
} else if (PinyinUtil.matchingPolyphone(pinyin)) {
entity.setIndex(PinyinUtil.gePolyphoneInitial(pinyin).toUpperCase());
entity.setPinyin(PinyinUtil.getPolyphoneRealPinyin(pinyin));
String hanzi = PinyinUtil.getPolyphoneRealHanzi(indexName);
entity.setIndexByField(hanzi);
// 把多音字的真实indexField重新赋值
item.setFieldIndexBy(hanzi);
} else {
entity.setIndex(INDEX_END_SIGN);
entity.setPinyin(pinyin);
entity.setIndexByField(item.getFieldIndexBy());
}
entity.setIndexTitle(entity.getIndex());
entity.setData(item);
entity.setOriginalPosition(i);
item.setFieldPinyinIndexBy(entity.getPinyin());
String inital = entity.getIndex();
List<EntityWrapper<T>> list;
if (!map.containsKey(inital)) {
list = new ArrayList<>();
list.add(new EntityWrapper<T>(entity.getIndex(), EntityWrapper.TYPE_TITLE));
map.put(inital, list);
} else {
list = map.get(inital);
}
list.add(entity);
}
ArrayList<EntityWrapper<T>> list = new ArrayList<>();
for (List<EntityWrapper<T>> indexableEntities : map.values()) {
Comparator comparator;
if (mCompareMode == MODE_FAST) {
comparator = new InitialComparator<T>();
Collections.sort(indexableEntities, comparator);
} else if (mCompareMode == MODE_ALL_LETTERS) {
comparator = new PinyinComparator<T>();
Collections.sort(indexableEntities, comparator);
}
list.addAll(indexableEntities);
}
return list;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private Handler getSafeHandler() {
if (mHandler == null) {
mHandler = new Handler(Looper.getMainLooper());
}
return mHandler;
}
}
`
from indexablerecyclerview.
Related Issues (20)
- 能否提供api外部直接设置索引Bar数据
- setDatas 时能不刷新 header吗?
- 土耳其语言首字母为I的识别出来不是i,希望作者能修复下。
- 1.3.0引入了重复的tinypinyin-android库(这个库没有被用到,工程里应该在sample project引入,而不是在lib里引入),而且PinyinUtil里面引入了的com.github.promeg.pinyinhelper.Pinyin更新不下来 HOT 1
- notifyItemChanged 能否暴漏出来
- 一个很离奇的XML崩溃报错 HOT 1
- 关于 拼音库【 TinyPinyin 】 依赖问题,可以参考下
- 滑动后 字母吸顶不显示 是什么鬼 HOT 1
- 请问 布局item上添加button按钮 点击请求网络 如何拿到当前item的信息作为参数上传?
- 请问怎么获取右侧indexbar
- 默认没有按照首字母排序
- jcenter跑路啦,有迁移计划吗 HOT 1
- 想要在适配器中获取元素的下标 position,怎么操作?
- 1.30版本 刷新方法被注释
- 大神,拼音的jar包有时候根本依赖不下来啊
- 热门和 定位顺序问题
- 无法滑动,我使用的是LinearLayoutManager HOT 1
- tinypinyin.lexicons 依赖冲突 HOT 4
- 关于header定制不灵活的建议
- 可以隐藏没有数据的 索引么
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from indexablerecyclerview.