Android RecycleView实现Item拖拽效果
基于公司产品的优化需求,其中一个需求涉及到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)
}
}
}
以上就是android recycleview实现item拖拽效果的详细内容,更多关于android recycleview拖拽item的资料请关注萬仟网其它相关文章!
看完文章,还可以扫描下面的二维码下载快手极速版领4元红包
除了扫码领红包之外,大家还可以在快手极速版做签到,看视频,做任务,参与抽奖,邀请好友赚钱)。
邀请两个好友奖最高196元,如下图所示:






