Skip to content

Instantly share code, notes, and snippets.

@webserveis
Created February 19, 2019 09:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save webserveis/2b7876b88a0f653e216f7ebddeddd3b5 to your computer and use it in GitHub Desktop.
Save webserveis/2b7876b88a0f653e216f7ebddeddd3b5 to your computer and use it in GitHub Desktop.
Drag and Swipe recyclerview
package com.example.webserveis.testkeyvalue;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.Collections;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
public class KeyValueAdapter extends RecyclerView.Adapter<KeyValueAdapter.MyViewHolder> implements
SwipeAndDragHelper.ItemTouchHelperAdapter {
private List<KeyValueItem> itemList;
private ItemTouchHelper touchHelper;
public KeyValueAdapter(List<KeyValueItem> data) {
this.itemList = data;
}
@NonNull
@Override
public KeyValueAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_layout, parent, false);
return new MyViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull KeyValueAdapter.MyViewHolder holder, int position) {
KeyValueItem item = itemList.get(position);
holder.mKey.setText(item.getKey());
holder.mValue.setText(item.getValue());
}
@Override
public int getItemCount() {
return itemList == null ? 0 : itemList.size();
}
public void updateDataSet(List<KeyValueItem> data) {
this.itemList = data;
notifyDataSetChanged();
}
@NonNull
public final List<KeyValueItem> getCurrentItems() {
return Collections.unmodifiableList(itemList);
}
@Override
public void onViewMoved(int oldPosition, int newPosition) {
Collections.swap(itemList, oldPosition, newPosition);
notifyItemMoved(oldPosition, newPosition);
}
@Override
public void onViewSwiped(int position) {
itemList.remove(position);
notifyItemRemoved(position);
}
public void setTouchHelper(ItemTouchHelper touchHelper) {
this.touchHelper = touchHelper;
}
public static class MyViewHolder extends RecyclerView.ViewHolder implements
SwipeAndDragHelper.ItemTouchHelperViewHolder {
private TextView mKey;
private TextView mValue;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
mKey = itemView.findViewById(R.id.text1);
mValue = itemView.findViewById(R.id.text2);
}
@Override
public void onItemSelected() {
itemView.setBackgroundColor(Color.LTGRAY);
}
@Override
public void onItemClear() {
itemView.setBackgroundColor(0);
}
}
}
package com.example.webserveis.testkeyvalue;
import java.util.Objects;
public class KeyValueItem {
private String key;
private String value;
public KeyValueItem(String k, String v) {
key = k;
value = v;
}
public KeyValueItem(KeyValueItem item) {
key = item.key;
value = item.value;
}
@Override
public boolean equals(Object o) {
if (o instanceof KeyValueItem) {
KeyValueItem that = (KeyValueItem) o;
return Objects.equals(key, that.key);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(key);
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
return "KeyValueItem{" +
"key='" + key + '\'' +
", value='" + value + '\'' +
'}';
}
}
package com.example.webserveis.testkeyvalue;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
import java.util.Random;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class KeyValueActivity extends AppCompatActivity {
private final String TAG = KeyValueActivity.class.getSimpleName();
public static final String KEY_VALUE_LIST_KEY = "key_value_list";
private RecyclerView mRecyclerView;
private KeyValueAdapter mAdapter;
private KeyValueViewModel mViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_key_value);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
mRecyclerView = findViewById(R.id.list);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG).setAction("Action", null).show();
for (KeyValueItem item : mAdapter.getCurrentItems()) {
Log.d(TAG, "sort: " + item);
}
}
});
initRecyclerView();
mViewModel = ViewModelProviders.of(this).get(KeyValueViewModel.class);
mViewModel.getKeyValueList().observe(this, new Observer<List<KeyValueItem>>() {
@Override
public void onChanged(List<KeyValueItem> keyValueItems) {
Log.d(TAG, "onChanged: " + keyValueItems.size());
mAdapter.updateDataSet(keyValueItems);
/* mAdapter.updateDataSet(list, true);
mAdapter.notifyDataSetChanged();*/
}
});
mViewModel.addItem(new KeyValueItem("user-agent", "google-chrome"));
mViewModel.addItem(new KeyValueItem("a", generateString(15)));
mViewModel.addItem(new KeyValueItem("b", generateString(15)));
mViewModel.addItem(new KeyValueItem("c", generateString(15)));
mViewModel.addItem(new KeyValueItem("d", generateString(15)));
mViewModel.addItem(new KeyValueItem("e", generateString(15)));
mViewModel.addItem(new KeyValueItem("f", generateString(15)));
mViewModel.addItem(new KeyValueItem(generateString(3), generateString(15)));
}
public void initRecyclerView() {
mAdapter = new KeyValueAdapter(null);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setHasFixedSize(true);
SwipeAndDragHelper swipeAndDragHelper = new SwipeAndDragHelper(mAdapter);
ItemTouchHelper touchHelper = new ItemTouchHelper(swipeAndDragHelper);
mAdapter.setTouchHelper(touchHelper);
mRecyclerView.setAdapter(mAdapter);
touchHelper.attachToRecyclerView(mRecyclerView);
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return false;
}
public String generateString(int length) {
final String SOURCES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
return generateString(new Random(), SOURCES, length);
}
public String generateString(Random random, String characters, int length) {
char[] text = new char[length];
for (int i = 0; i < length; i++) {
text[i] = characters.charAt(random.nextInt(characters.length()));
}
return new String(text);
}
}
package com.example.webserveis.testkeyvalue;
import android.graphics.Canvas;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
/*
https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf
https://github.com/iPaulPro/Android-ItemTouchHelper-Demo
https://www.journaldev.com/23208/android-recyclerview-drag-and-drop
https://therubberduckdev.wordpress.com/2017/10/24/android-recyclerview-drag-and-drop-and-swipe-to-dismiss/
https://codeburst.io/android-swipe-menu-with-recyclerview-8f28a235ff28
*/
public class SwipeAndDragHelper extends ItemTouchHelper.Callback {
private static final float ALPHA_FULL = 1.0f;
private ItemTouchHelperAdapter touchAdapter;
public SwipeAndDragHelper(ItemTouchHelperAdapter contract) {
this.touchAdapter = contract;
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
/* if (viewHolder instanceof SectionHeaderViewHolder) {
return 0;
}*/
// Set movement flags based on the layout manager, avoid swipe in GridLayout
if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
final int swipeFlags = 0;
return makeMovementFlags(dragFlags, swipeFlags);
} else {
final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
touchAdapter.onViewMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
touchAdapter.onViewSwiped(viewHolder.getAdapterPosition());
}
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
// Fade out the view as it is swiped out of the parent's bounds
final float alpha = ALPHA_FULL - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
viewHolder.itemView.setAlpha(alpha);
viewHolder.itemView.setTranslationX(dX);
} else {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
// We only want the active item to change
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Let the view holder know that this item is being moved or dragged
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemSelected();
}
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
viewHolder.itemView.setAlpha(ALPHA_FULL);
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Tell the view holder it's time to restore the idle state
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemClear();
}
}
public interface ItemTouchHelperAdapter {
void onViewMoved(int oldPosition, int newPosition);
void onViewSwiped(int position);
}
public interface ItemTouchHelperViewHolder {
void onItemSelected();
void onItemClear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment