如何使用android中的拖放框架从一个LinearLayout切换到另一个LinearLayout
Posted
技术标签:
【中文标题】如何使用android中的拖放框架从一个LinearLayout切换到另一个LinearLayout【英文标题】:How to swap from one LinearLayout to another LinearLayout using drag and drop framework in android 【发布时间】:2020-01-07 07:36:36 【问题描述】:TextView
和 ImageView
合二为一 LinearLayout
。我想以这样的方式将第一个LinearLayout
拖到第二个LinearLayout
,当我将第一个线性拖放到第二个LinearLayout
时,它的TextView
和ImageView
应该首先出现LinearLayout
,反之亦然。我已经完成了研发,我发现将布局从第一个拖放到第二个,但第二个布局没有出现在第一个布局中。
问题是布局没有得到交换。我可以从第一个拖放到第二个,但不能从第一个拖放到第二个。
下面是我的片段:
public class MoreDestinationFragment extends Fragment implements View.OnClickListener, View.OnTouchListener, View.OnDragListener
private OnFragmentInteractionListener mListener;
private LinearLayout llNews;
public MoreDestinationFragment()
// Required empty public constructor
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment_more_destination, container, false);
llNews = view.findViewById(R.id.ll_new);
llNews.setOnClickListener(this);
llNews.setOnTouchListener(this);
llNews.setOnDragListener(this);
return view;
@Override
public void onClick(View view)
switch (view.getId())
case R.id.ll_new:
Navigation.findNavController(view).navigate(R.id.action_moreDestinationFragment_to_newsDestinationFragment);
break;
@Override
public boolean onDrag(View layoutview, DragEvent dragevent)
int action = dragevent.getAction();
switch (action)
case DragEvent.ACTION_DRAG_STARTED:
Log.d("xxxxxxx", "Drag event started");
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.d("xxxxxxx", "Drag event entered into " + layoutview.toString());
break;
case DragEvent.ACTION_DRAG_EXITED:
Log.d("xxxxxxx", "Drag event exited from " + layoutview.toString());
break;
case DragEvent.ACTION_DROP:
Log.d("xxxxxxx", "Dropped");
View view = (View) dragevent.getLocalState();
ViewGroup owner = (ViewGroup) view.getParent();
owner.removeView(view);
LinearLayout container = (LinearLayout) layoutview;
container.addView(view);
view.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.d("xxxxxxx", "Drag ended");
break;
default:
break;
return true;
@Override
public boolean onTouch(View view, MotionEvent motionEvent)
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN)
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(null, shadowBuilder, view, 0);
view.setVisibility(View.INVISIBLE);
return true;
else
return false;
public interface OnFragmentInteractionListener
void onFragmentInteraction(Uri uri);
请帮帮我,请提供解决方案。谢谢。
【问题讨论】:
Why don't you useRecyclerView
with ItemTouchHelper
@NileshRathod 我不知道它对我有什么帮助:(
查看上述评论中的链接或在谷歌中搜索ItemTouchHelper
@NileshRathod 在ItemTouchHelper
的帮助下,我们可以进行拖放和滑动或关闭,但不能交换视图,反之亦然。
是的,这是可能的,但您已经为该功能创建了逻辑
【参考方案1】:
您可以使用
RecyclerView
和GridLayoutManager
来代替 几个LinearLayout
如下:
步骤:
将以下依赖项添加到 gradle 应用模块中
// RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.0.0'
// CardView
implementation 'androidx.cardview:cardview:1.0.0'
主布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recyclerview"
android:layout_
android:layout_
tools:context=".MainActivity">
</androidx.recyclerview.widget.RecyclerView>
列表项布局(RecyclerView的)
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:layout_marginBottom="4dp"
android:clickable="true"
android:elevation="4dp"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
card_view:cardCornerRadius="10dp"
card_view:cardUseCompatPadding="true"
tools:ignore="UnusedAttribute">
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:padding="4dp">
<ImageView
android:id="@+id/imThumbnail"
android:layout_
android:layout_
android:layout_gravity="center"
tools:background="@drawable/ic_android_black_24dp" />
<TextView
android:id="@+id/tvTitle"
android:layout_
android:layout_
android:layout_gravity="center"
tools:text="Android" />
</LinearLayout>
</androidx.cardview.widget.CardView>
要在 RecyclerView 中填充的项目的模型类
public class Item
private String mTitle;
private int mThumbnail;
public String getTitle()
return mTitle;
public Item(String title, int thumbnail)
this.mTitle = title;
mThumbnail = thumbnail;
public void setTitle(String title)
this.mTitle = title;
public int getThumbnail()
return mThumbnail;
public void setThumbnail(int thumbnail)
mThumbnail = thumbnail;
RecyclerView 适配器
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder>
List<Item> mItems;
public Adapter(ArrayList items)
mItems = items;
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
holder.bindViews(mItems.get(position));
@Override
public int getItemCount()
return mItems.size();
class ViewHolder extends RecyclerView.ViewHolder
TextView mTitle;
ImageView mThumbnail;
ViewHolder(@NonNull View itemView)
super(itemView);
mTitle = itemView.findViewById(R.id.tvTitle);
mThumbnail = itemView.findViewById(R.id.imThumbnail);
void bindViews(Item item)
mTitle.setText(item.getTitle());
mThumbnail.setImageResource(item.getThumbnail());
最后是主要行为
利用ItemTouchHelper
类拖动功能并使用attachToRecyclerView()
方法将其附加到RecyclerView
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity
private ArrayList<Item> mItems;
private Adapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
populateItems();
mAdapter = new Adapter(mItems);
RecyclerView recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
recyclerView.setAdapter(mAdapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP |
ItemTouchHelper.DOWN |
ItemTouchHelper.LEFT |
ItemTouchHelper.RIGHT,
0)
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target)
moveItem(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return false;
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction)
);
itemTouchHelper.attachToRecyclerView(recyclerView);
private void populateItems()
mItems = new ArrayList<>();
mItems.add(new Item("Android", R.drawable.ic_android_black_24dp));
mItems.add(new Item("Archive", R.drawable.ic_archive_black_24dp));
mItems.add(new Item("Alarm", R.drawable.ic_access_alarm_black_24dp));
mItems.add(new Item("Block", R.drawable.ic_block_black_24dp));
mItems.add(new Item("CAll", R.drawable.ic_call_black_24dp));
mItems.add(new Item("Android", R.drawable.ic_android_black_24dp));
mItems.add(new Item("Archive", R.drawable.ic_archive_black_24dp));
mItems.add(new Item("Alarm", R.drawable.ic_access_alarm_black_24dp));
mItems.add(new Item("Block", R.drawable.ic_block_black_24dp));
mItems.add(new Item("CAll", R.drawable.ic_call_black_24dp));
private void moveItem(int oldPos, int newPos)
Item temp = mItems.get(oldPos);
mItems.set(oldPos, mItems.get(newPos));
mItems.set(newPos, temp);
mAdapter.notifyItemMoved(oldPos, newPos);
结果在这里
希望能满足你的需求
【讨论】:
以上是关于如何使用android中的拖放框架从一个LinearLayout切换到另一个LinearLayout的主要内容,如果未能解决你的问题,请参考以下文章