Created
February 19, 2019 09:35
-
-
Save webserveis/2b7876b88a0f653e216f7ebddeddd3b5 to your computer and use it in GitHub Desktop.
Drag and Swipe recyclerview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 + '\'' + | |
'}'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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