From cb1bd0e1316fed5f9e4abca4d361e897f8a61eb6 Mon Sep 17 00:00:00 2001 From: 13372038054 <550906320@qq.com> Date: Thu, 30 Nov 2017 11:50:52 +0800 Subject: [PATCH] fix onItemClick, OnItemLongClick position wrong when use RecyclerView animation to remove or insert item --- .../mvp/presenter/BookmarkPresenter.java | 6 +- .../openhub/mvp/presenter/TracePresenter.java | 4 +- .../mvp/presenter/base/BasePresenter.java | 4 ++ .../ui/activity/RepositoryActivity.java | 4 +- .../ui/activity/base/ListActivity.java | 5 +- .../ui/adapter/CommitFilesAdapter.java | 7 +-- .../ui/adapter/NotificationsAdapter.java | 6 +- .../openhub/ui/adapter/SettingsAdapter.java | 1 + .../openhub/ui/adapter/TraceAdapter.java | 6 +- .../openhub/ui/adapter/base/BaseAdapter.java | 54 ++++-------------- .../ui/adapter/base/BaseViewHolder.java | 57 ++++++++++++++++++- .../ui/fragment/ProfileInfoFragment.java | 4 +- .../ui/fragment/RepoFilesFragment.java | 10 +--- .../ui/fragment/base/ListFragment.java | 5 +- 14 files changed, 100 insertions(+), 73 deletions(-) diff --git a/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/BookmarkPresenter.java b/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/BookmarkPresenter.java index 9e2ddb4b..62d61833 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/BookmarkPresenter.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/BookmarkPresenter.java @@ -17,7 +17,6 @@ import javax.inject.Inject; import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; /** * Created by ThirtyDegreesRay on 2017/11/22 15:59:45 @@ -81,13 +80,14 @@ public void loadBookmarks(int page) { public void removeBookmark(int position) { removedBookmark = bookmarks.remove(position); removedPosition = position; - daoSession.getBookmarkDao().deleteByKey(removedBookmark.getId()); + rxDBExecute(() -> daoSession.getBookmarkDao().deleteByKey(removedBookmark.getId())); } @Override public void undoRemoveBookmark() { bookmarks.add(removedPosition, removedBookmark); - daoSession.getBookmarkDao().insert(removedBookmark); mView.notifyItemAdded(removedPosition); + rxDBExecute(() -> daoSession.getBookmarkDao().insert(removedBookmark)); } + } diff --git a/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/TracePresenter.java b/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/TracePresenter.java index b1723c99..d9d7f229 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/TracePresenter.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/TracePresenter.java @@ -79,14 +79,14 @@ public void loadTraceList(int page) { public void removeTrace(int position) { removedTrace = traceList.remove(position); removedPosition = position; - daoSession.getTraceDao().deleteByKey(removedTrace.getId()); + rxDBExecute(() -> daoSession.getTraceDao().deleteByKey(removedTrace.getId())); } @Override public void undoRemoveTrace() { traceList.add(removedPosition, removedTrace); - daoSession.getTraceDao().insert(removedTrace); mView.notifyItemAdded(removedPosition); + rxDBExecute(() -> daoSession.getTraceDao().insert(removedTrace)); } @Override diff --git a/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/base/BasePresenter.java b/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/base/BasePresenter.java index fac8858c..5bf92ae6 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/base/BasePresenter.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/mvp/presenter/base/BasePresenter.java @@ -322,6 +322,10 @@ private boolean checkIsUnauthorized(Throwable error){ return false; } + public void rxDBExecute(@NonNull Runnable runnable){ + daoSession.rxTx().run(runnable).subscribe(); + } + @NonNull protected String getLoadTip() { diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/activity/RepositoryActivity.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/activity/RepositoryActivity.java index a20c9ddc..515502b4 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/activity/RepositoryActivity.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/activity/RepositoryActivity.java @@ -32,7 +32,7 @@ import com.thirtydegreesray.openhub.mvp.presenter.RepositoryPresenter; import com.thirtydegreesray.openhub.ui.activity.base.PagerActivity; import com.thirtydegreesray.openhub.ui.adapter.BranchesAdapter; -import com.thirtydegreesray.openhub.ui.adapter.base.BaseAdapter; +import com.thirtydegreesray.openhub.ui.adapter.base.BaseViewHolder; import com.thirtydegreesray.openhub.ui.adapter.base.FragmentPagerModel; import com.thirtydegreesray.openhub.ui.fragment.ActivityFragment; import com.thirtydegreesray.openhub.ui.fragment.CommitsFragment; @@ -240,7 +240,7 @@ public void onClick(DialogInterface dialog, int which) { }) .show(); - branchesAdapter.setOnItemClickListener(new BaseAdapter.OnItemClickListener() { + branchesAdapter.setOnItemClickListener(new BaseViewHolder.OnItemClickListener() { @Override public void onItemClick(int position, @NonNull View view) { Branch branch = list.get(position); diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/activity/base/ListActivity.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/activity/base/ListActivity.java index 92bc3c98..ee7f71ae 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/activity/base/ListActivity.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/activity/base/ListActivity.java @@ -11,6 +11,7 @@ import com.thirtydegreesray.openhub.R; import com.thirtydegreesray.openhub.mvp.contract.base.IBaseContract; import com.thirtydegreesray.openhub.ui.adapter.base.BaseAdapter; +import com.thirtydegreesray.openhub.ui.adapter.base.BaseViewHolder; import javax.inject.Inject; @@ -24,8 +25,8 @@ public abstract class ListActivity

extends BaseActivity

implements IBaseContract.View, - BaseAdapter.OnItemClickListener, - BaseAdapter.OnItemLongClickListener { + BaseViewHolder.OnItemClickListener, + BaseViewHolder.OnItemLongClickListener { @BindView(R.id.recycler_view) protected RecyclerView recyclerView; @Inject protected A adapter; diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/CommitFilesAdapter.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/CommitFilesAdapter.java index 3e6c044e..6455bcdc 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/CommitFilesAdapter.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/CommitFilesAdapter.java @@ -7,7 +7,6 @@ import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v7.widget.AppCompatImageView; -import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.TextView; @@ -29,7 +28,7 @@ * Created by ThirtyDegreesRay on 2017/10/18 15:09:19 */ -public class CommitFilesAdapter extends BaseAdapter> { @Inject @@ -47,7 +46,7 @@ protected int getLayoutId(int viewType) { } @Override - protected RecyclerView.ViewHolder getViewHolder(View itemView, int viewType) { + protected BaseViewHolder getViewHolder(View itemView, int viewType) { if(viewType == 0){ return new PathViewHolder(itemView); }else{ @@ -61,7 +60,7 @@ public int getItemViewType(int position) { } @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { + public void onBindViewHolder(@NonNull BaseViewHolder viewHolder, int position) { super.onBindViewHolder(viewHolder, position); if (viewHolder instanceof PathViewHolder) { PathViewHolder holder = (PathViewHolder) viewHolder; diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/NotificationsAdapter.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/NotificationsAdapter.java index 3a94524c..7a435625 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/NotificationsAdapter.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/NotificationsAdapter.java @@ -36,7 +36,7 @@ * Created by ThirtyDegreesRay on 2017/11/6 20:05:32 */ -public class NotificationsAdapter extends BaseAdapter> { @Inject @@ -54,7 +54,7 @@ protected int getLayoutId(int viewType) { } @Override - protected RecyclerView.ViewHolder getViewHolder(View itemView, int viewType) { + protected BaseViewHolder getViewHolder(View itemView, int viewType) { if(viewType == 0){ return new RepoViewHolder(itemView); } else { @@ -68,7 +68,7 @@ public int getItemViewType(int position) { } @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { + public void onBindViewHolder(@NonNull BaseViewHolder viewHolder, int position) { super.onBindViewHolder(viewHolder, position); if(viewHolder instanceof RepoViewHolder){ RepoViewHolder holder = (RepoViewHolder) viewHolder; diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/SettingsAdapter.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/SettingsAdapter.java index 0ae660be..7af897f2 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/SettingsAdapter.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/SettingsAdapter.java @@ -29,6 +29,7 @@ public class SettingsAdapter extends BaseAdapter { private ItemEventListener itemEventListener; + private final int TAG_POSITION = R.id.position_tag; @Inject public SettingsAdapter(Context context) { diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/TraceAdapter.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/TraceAdapter.java index cf81eae5..578c267b 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/TraceAdapter.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/TraceAdapter.java @@ -34,7 +34,7 @@ * Created by ThirtyDegreesRay on 2017/11/23 10:35:13 */ -public class TraceAdapter extends BaseAdapter +public class TraceAdapter extends BaseAdapter implements StickyRecyclerHeadersAdapter{ @Inject @@ -52,7 +52,7 @@ protected int getLayoutId(int viewType) { } @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) { super.onBindViewHolder(holder, position); TraceExt model = data.get(position); if(getItemViewType(position) == 0){ @@ -91,7 +91,7 @@ public int getItemViewType(int position) { } @Override - protected RecyclerView.ViewHolder getViewHolder(View itemView, int viewType) { + protected BaseViewHolder getViewHolder(View itemView, int viewType) { if(viewType == 0){ return new UserViewHolder(itemView); } else { diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/base/BaseAdapter.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/base/BaseAdapter.java index 87e8fb2e..07836028 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/base/BaseAdapter.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/base/BaseAdapter.java @@ -11,7 +11,6 @@ import android.view.ViewGroup; import android.widget.Toast; -import com.thirtydegreesray.openhub.R; import com.thirtydegreesray.openhub.ui.fragment.base.BaseFragment; import java.util.ArrayList; @@ -21,15 +20,15 @@ * 适配器基类 * Created by ThirtyDegreesRay on 2016/7/27 19:49 */ -public abstract class BaseAdapter +public abstract class BaseAdapter extends RecyclerView.Adapter - implements View.OnClickListener, View.OnLongClickListener{ + implements BaseViewHolder.OnItemClickListener, BaseViewHolder.OnItemLongClickListener{ //item点击回调 - private OnItemClickListener mOnItemClickListener; + private BaseViewHolder.OnItemClickListener mOnItemClickListener; //item长按回调 - private OnItemLongClickListener mOnItemLongClickListener; + private BaseViewHolder.OnItemLongClickListener mOnItemLongClickListener; /** * 数据列表 @@ -42,8 +41,6 @@ public abstract class BaseAdapter getData() { * 设置item点击事件 * @param onItemClickListener */ - public void setOnItemClickListener(OnItemClickListener onItemClickListener) { + public void setOnItemClickListener(BaseViewHolder.OnItemClickListener onItemClickListener) { this.mOnItemClickListener = onItemClickListener; } @@ -77,7 +74,7 @@ public void setOnItemClickListener(OnItemClickListener onItemClickListener) { * 设置item长按事件 * @param onItemLongClickListener */ - public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) { + public void setOnItemLongClickListener(BaseViewHolder.OnItemLongClickListener onItemLongClickListener) { this.mOnItemLongClickListener = onItemLongClickListener; } @@ -92,14 +89,12 @@ public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @Override public void onBindViewHolder(@NonNull VH holder, final int position) { - holder.itemView.setTag(TAG_POSITION, position); - if(mOnItemClickListener != null){ - holder.itemView.setOnClickListener(this); + holder.setOnItemClickListener(this); } if(mOnItemLongClickListener != null){ - holder.itemView.setOnLongClickListener(this); + holder.setOnItemLongClickListener(this); } } @@ -124,45 +119,20 @@ public int getItemCount() { */ protected abstract VH getViewHolder(View itemView, int viewType); - /** - * RecyclerView item点击监听 - */ - public interface OnItemClickListener{ - /** - * RecyclerView item点击 - * @param position 位置 - */ - void onItemClick(int position, @NonNull View view); - } - /** - * RecyclerView item长按监听 - */ - public interface OnItemLongClickListener{ - /** - * RecyclerView item长按 - * @param position 位置 - * @return - */ - boolean onItemLongClick(int position, @NonNull View view); - } protected void showShortToast(String msg){ Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } @Override - public void onClick(View v) { - mOnItemClickListener.onItemClick(getPositionByView(v), v); + public void onItemClick(int position, @NonNull View view) { + mOnItemClickListener.onItemClick(position, view); } @Override - public boolean onLongClick(View v) { - return mOnItemLongClickListener.onItemLongClick(getPositionByView(v), v); - } - - protected int getPositionByView(View view){ - return (int) view.getTag(TAG_POSITION); + public boolean onItemLongClick(int position, @NonNull View view) { + return mOnItemLongClickListener.onItemLongClick(position, view); } @NonNull protected String getString(@StringRes int resId){ diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/base/BaseViewHolder.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/base/BaseViewHolder.java index 739c38ba..d32d1e9e 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/base/BaseViewHolder.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/adapter/base/BaseViewHolder.java @@ -12,11 +12,66 @@ * BasicViewHolder * Created by ThirtyDegreesRay on 2016/7/27 20:20 */ -public class BaseViewHolder extends RecyclerView.ViewHolder{ +public class BaseViewHolder extends RecyclerView.ViewHolder + implements View.OnClickListener, View.OnLongClickListener{ + + //item点击回调 + private OnItemClickListener mOnItemClickListener; + + //item长按回调 + private OnItemLongClickListener mOnItemLongClickListener; public BaseViewHolder(@NonNull View itemView) { super(itemView); ButterKnife.bind(this, itemView); } + public void setOnItemClickListener(OnItemClickListener onItemClickListener) { + this.mOnItemClickListener = onItemClickListener; + itemView.setOnClickListener(this); + } + + public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) { + this.mOnItemLongClickListener = onItemLongClickListener; + itemView.setOnLongClickListener(this); + } + + @Override + public void onClick(View v) { + if(mOnItemClickListener != null && getAdapterPosition() != RecyclerView.NO_POSITION){ + mOnItemClickListener.onItemClick(getAdapterPosition(), v); + } + } + + @Override + public boolean onLongClick(View v) { + if(mOnItemLongClickListener != null && getAdapterPosition() != RecyclerView.NO_POSITION){ + return mOnItemLongClickListener.onItemLongClick(getAdapterPosition(), v); + } + return false; + } + + /** + * RecyclerView item点击监听 + */ + public interface OnItemClickListener{ + /** + * RecyclerView item点击 + * @param position 位置 + */ + void onItemClick(int position, @NonNull View view); + } + + /** + * RecyclerView item长按监听 + */ + public interface OnItemLongClickListener{ + /** + * RecyclerView item长按 + * @param position 位置 + * @return + */ + boolean onItemLongClick(int position, @NonNull View view); + } + } diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/ProfileInfoFragment.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/ProfileInfoFragment.java index 69d1024e..593aef63 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/ProfileInfoFragment.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/ProfileInfoFragment.java @@ -24,7 +24,7 @@ import com.thirtydegreesray.openhub.ui.activity.RepoListActivity; import com.thirtydegreesray.openhub.ui.activity.UserListActivity; import com.thirtydegreesray.openhub.ui.adapter.UsersAdapter; -import com.thirtydegreesray.openhub.ui.adapter.base.BaseAdapter; +import com.thirtydegreesray.openhub.ui.adapter.base.BaseViewHolder; import com.thirtydegreesray.openhub.ui.fragment.base.BaseFragment; import com.thirtydegreesray.openhub.util.AppOpener; import com.thirtydegreesray.openhub.util.BundleHelper; @@ -44,7 +44,7 @@ public class ProfileInfoFragment extends BaseFragment implements IProfileInfoContract.View, - BaseAdapter.OnItemClickListener{ + BaseViewHolder.OnItemClickListener{ @BindView(R.id.name) TextView name; @BindView(R.id.bio) TextView bio; diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/RepoFilesFragment.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/RepoFilesFragment.java index c7ebc2ad..7e0ff809 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/RepoFilesFragment.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/RepoFilesFragment.java @@ -24,7 +24,6 @@ import com.thirtydegreesray.openhub.ui.activity.base.PagerActivity; import com.thirtydegreesray.openhub.ui.adapter.FilePathAdapter; import com.thirtydegreesray.openhub.ui.adapter.RepoFilesAdapter; -import com.thirtydegreesray.openhub.ui.adapter.base.BaseAdapter; import com.thirtydegreesray.openhub.ui.fragment.base.ListFragment; import com.thirtydegreesray.openhub.util.BundleHelper; @@ -100,12 +99,9 @@ protected void initFragment(Bundle savedInstanceState) { pathRecyclerView.setLayoutManager( new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false)); pathRecyclerView.setAdapter(filePathAdapter); - filePathAdapter.setOnItemClickListener(new BaseAdapter.OnItemClickListener() { - @Override - public void onItemClick(int position, @NonNull View view) { - mPresenter.loadFiles(filePathAdapter.getData().get(position).getFullPath(), false); - } - }); + filePathAdapter.setOnItemClickListener((position, view) -> + mPresenter.loadFiles(filePathAdapter.getData().get(position).getFullPath(), false) + ); } @Override diff --git a/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/base/ListFragment.java b/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/base/ListFragment.java index 958f693c..b5071ddf 100644 --- a/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/base/ListFragment.java +++ b/app/src/main/java/com/thirtydegreesray/openhub/ui/fragment/base/ListFragment.java @@ -15,6 +15,7 @@ import com.thirtydegreesray.openhub.R; import com.thirtydegreesray.openhub.mvp.contract.base.IBaseContract; import com.thirtydegreesray.openhub.ui.adapter.base.BaseAdapter; +import com.thirtydegreesray.openhub.ui.adapter.base.BaseViewHolder; import com.thirtydegreesray.openhub.util.NetHelper; import com.thirtydegreesray.openhub.util.PrefUtils; import com.thirtydegreesray.openhub.util.ViewUtils; @@ -32,8 +33,8 @@ public abstract class ListFragment

extends BaseFragment

implements IBaseContract.View, - BaseAdapter.OnItemClickListener, - BaseAdapter.OnItemLongClickListener, + BaseViewHolder.OnItemClickListener, + BaseViewHolder.OnItemLongClickListener, SwipeRefreshLayout.OnRefreshListener{ @BindView(R.id.refresh_layout) protected SwipeRefreshLayout refreshLayout;