基于公司產品的優化需求,其中一個需求涉及到RecycleView的拖拽,以及拖拽后item位置的持久化,目的是可以用戶自定義界面偏好,并在用戶下次進入本界面后,之前設定的偏好仍然有效,我寫了一個小Demo用作演示效果,
先看效果(只看效果,不看顏值)

步驟1、建介面檔案ItemTouchHelperViewHolder,該介面檔案中描述的是選中和放開當前Item呼叫的方法,
public interface ItemTouchHelperViewHolder {
void onItemSelected(); //選中item
void onItemCleared();//放開item
}
步驟2、寫Item得ViewHolder的類,該類需要繼承RecyclerView.ViewHolder類,同時要實作步驟中的介面,
public class ItemViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
private TextView tvName;
public TextView getTvName() {
return tvName;
}
public void setTvName(TextView tvName) {
this.tvName = tvName;
}
public ItemViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_item_name);
}
@Override
public void onItemSelected() {
tvName.setBackgroundColor(Color.GRAY);
}
@Override
public void onItemCleared() {
tvName.setBackgroundColor(Color.YELLOW);}
}
步驟3、建立介面檔案ItemTouchHelperAdapter,該檔案中描寫的是移動RecycleView的Item時會呼叫的方法,
public interface ItemTouchHelperAdapter {
void onItemMove(int fromPosition,int toPosition);
}
步驟4、實作一個配接器,繼承RecyclerView.Adapter<ItemViewHolder>,同時實作步驟3的介面,
public class RecyclerGridAdapter extends RecyclerView.Adapter<ItemViewHolder> implements ItemTouchHelperAdapter {
private ArrayList<String> localDataSet;
private SharedPreferences sp;
private SharedPreferences.Editor spEditor;
final static String SAVE_KEY = "star_sort";
final static String USER_PREFERENCE = "user_preference";
private Context context;
public RecyclerGridAdapter(ArrayList<String> dataSet,Context context) {
String defaultStr = dataSet.toString();
if(context != null){
this.context = context;
sp = context.getSharedPreferences(USER_PREFERENCE,Context.MODE_PRIVATE);
spEditor = sp.edit();
String saveString = sp.getString(SAVE_KEY,defaultStr);
//考慮,若要更改資料源,需要怎么實作 todo
String[] splitStr = saveString.replace("[","").replace("]","").replace(" ","").split(",");
localDataSet = new ArrayList();
localDataSet.addAll(Arrays.asList(splitStr));
}
}
@NonNull
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_holder_layout, parent, false);
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
holder.getTvName().setText(localDataSet.get(position));
}
@Override
public int getItemCount() {
return localDataSet.size();
}
@Override
public void onItemMove(int fromPosition, int toPosition) {
String prve = localDataSet.remove(fromPosition);
if((toPosition > fromPosition) && (localDataSet.size() <= toPosition)){
//將當前item移至最后一位
localDataSet.add(prve);
}else{
localDataSet.add(toPosition, prve);
}
notifyItemMoved(fromPosition, toPosition);
spEditor.putString(SAVE_KEY,localDataSet.toString());
spEditor.apply();
}
}
步驟5、實作ItemTouchHelper.Callback介面,至于什么是ItemTouchHelper,網上一查很多解釋,我這不做闡述了,
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
private ItemTouchHelperAdapter adapter;
public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
this.adapter = adapter;
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeFlag(ItemTouchHelper.ACTION_STATE_DRAG, dragFlags);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
if (viewHolder.getItemViewType() != target.getItemViewType()) {
return false;
}
adapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
ItemTouchHelperViewHolder itemTouchHelperViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemTouchHelperViewHolder.onItemSelected();
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
ItemViewHolder itemViewHolder = (ItemViewHolder) viewHolder;
itemViewHolder.onItemCleared();
}
}
步驟6,現在就可以呼叫啦,基于步驟5實作的ItemToucherHelper.Callback實體構建ItemTouchHelper實體,然后attach給RecycleView就好啦,
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
with(viewBinding){
var data = ArrayList<String>()
var index = 10
while (index-- >0){
data.add(index.toString())
}
var adapter = RecyclerGridAdapter(data,this@MainActivity)
recycleTest.layoutManager = GridLayoutManager(this@MainActivity,4)
recycleTest.adapter = adapter
var callback = SimpleItemTouchHelperCallback(adapter)
var itemTouchHelper = ItemTouchHelper(callback)
itemTouchHelper.attachToRecyclerView(recycleTest)
}
}
}
就好啦,甘甘丹丹,整挺好,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/403992.html
標籤:其他
上一篇:axios較常用的全域配置
