Git Product home page Git Product logo

Comments (26)

qssq666123 avatar qssq666123 commented on September 8, 2024

所以传递 null导致的结果就是
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024
 singerHeaderAdapter.addDatas(mRecommendSingers);
            singerHeaderAdapter.notifyDataSetChanged(); 我加了非空判断,这样还是没有数据。。

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

我尝试第一次初始化,在网格布局graidlayout, 中 头部区域 显示的是空白。

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

而且头部区域无法滚动上去只能通过右边定位

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

再说一次 grid的方式头部无法正常使用。。。而且那个区域滚动不上去。

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

使用NestedScrollView 嵌套 右边索引又没有了。

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

改了 一下 设置管理器功能可是又有地方出问题了

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.

qssq666123 avatar qssq666123 commented on September 8, 2024

而且头部是竖排。

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

大神啥时候在线呀,我得技术太烂不知道咋修复

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

这次更新顺便加上一个功能吧,就是右边覆盖层问题,已经置顶的,我这里也弄了。

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

另外建议弄个关键字的头部 既然不支持我就打算另辟蹊径 比如 置顶叫★, 其他的列为 #最后面

from indexablerecyclerview.

YoKeyword avatar YoKeyword commented on September 8, 2024

头部问题: 先让页面显示一个loading, 然后网络数据返回时,再初始化RecyclerView ,头部这块 视觉上就是正常的了

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

现在的问题是头部不支持grid,,所以我现在在写★索引。

from indexablerecyclerview.

YoKeyword avatar YoKeyword commented on September 8, 2024

如果你头部的Grid的条目不多的话,建议自定义一个View,负责装载这些条目;

如果Grid真是复杂而且动态性很大,建议自己fork下代码改造

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

只是基于gridview加一个头部而已 结果不行

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

空白

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

各种改都没搞定 不会改

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

现在改成★作为索引顶部结果出现了重复的索引五角星

from indexablerecyclerview.

YoKeyword avatar YoKeyword commented on September 8, 2024

哦哦, GridView是小伙伴提的PR, 头部兼容性上次我看了好像没问题

最近个人非常忙,可以不能及时维护.. 暂时可以自己改造下~

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

空白,改了下合并了终于显示头部了但是是单列,而且 有地方结果空指针 判断空指针返回结果所有头部没有了,问题也U来越多 不清楚整个代码没法继续了

from indexablerecyclerview.

YoKeyword avatar YoKeyword commented on September 8, 2024

上次issue说,这个库的目标是 比较大众的需求, 你的需求挺特殊,拿这个库改的话,一些不熟悉的地方会踩坑,建议自己写一套,可维护性更高

from indexablerecyclerview.

YoKeyword avatar YoKeyword commented on September 8, 2024

你的需求github上应该找不到对应的库,都需要自己修改,可以考虑研究一波,自己定制一个

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

--没想到这需求挑战项目极限了,希望
![Uploading image.pn您老弄得越来越完善

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

我现在的解决方法只有这样了,要置顶的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.

qssq666123 avatar qssq666123 commented on September 8, 2024

最后感谢,达到了置顶需求就可以了,在a-z之外的 五角星排序主要是标题不雅观需要在适配器里面处理一下包含五角星了。

from indexablerecyclerview.

qssq666123 avatar qssq666123 commented on September 8, 2024

解决了置顶变色,已经置顶某些单独的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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.