最近看了视频学习了类似网易的频道拖动效果,就跟着敲了几遍,下面是总结和记录:
先看效果图,
实现的效果:
1.长按按钮,实现btn的拖拽,原来的位置要有一个虚线为底的btn
2.当拖拽放到某个位置时,原来的位置的btn要删除掉,拖拽的btn放入当前位置。btn背景色恢复。
具体代码:
java文件:
···
public class MyStuActivity extends AppCompatActivity {
private Button button;
private GridLayout layout;
private View selectView;
private List<Rect> rects;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_stu);
button = findViewById(R.id.btn);
layout = findViewById(R.id.layout_myGrid);
/**
* 在gridlayout中做拖拽监听
*/
layout.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
/**
* 开始拖拽,初始化矩形,这里面的每个矩形就是初始textview的位置,
* 利用矩形判断当前坐标是否在矩形内,如果再矩形内,就删除原来的textview,
* 并在当前位置添加拖拽的textView
*/
initRects();
break;
case DragEvent.ACTION_DRAG_LOCATION:
//此部分是拖拽时的事件,只要在拖拽,就会一直响应此事件
int pos = isConstans(event);
if (pos > -1 && selectView != null && selectView != layout.getChildAt(pos)) {
//先删除原来的view
layout.removeView(selectView);
//添加显得veiw
layout.addView(selectView, pos);
}
break;
case DragEvent.ACTION_DRAG_ENDED:
//拖拽结束必定发生的事件,设置textview的背景
selectView.setEnabled(true);
break;
}
return true;
}
});
}
/**
* 是否包含
*
* @param event
* @return
*/
private int isConstans(DragEvent event) {
for (int i = 0; i < rects.size(); i++) {
if (rects.get(i).contains((int) event.getX(), (int) event.getY())) {
return i;
}
}
return -1;
}
//初始化矩形
private void initRects() {
rects = new ArrayList<>();
for (int i = 0; i < layout.getChildCount(); i++) {
Rect rect = new Rect(layout.getChildAt(i).getLeft(), layout.getChildAt(i).getTop(),
layout.getChildAt(i).getRight(), layout.getChildAt(i).getBottom());
rects.add(rect);
}
}
//btn响应事件,点击添加一个textview
public void addMyItem(final View view) {
//添加一個子項
int margin = 10;
final TextView textView = new TextView(MyStuActivity.this);
textView.setText("新闻");
textView.setTextColor(getResources().getColor(R.color.colorBlack));
textView.setGravity(Gravity.CENTER);
//背景是一个选择器
textView.setBackground(getResources().getDrawable(R.drawable.selector_tv));
textView.setTextSize(20);
textView.setPadding(margin, margin, margin, margin);
//设置宽、高、margin时使用的layoutParams,注意此处的layoutParams必须是其父布局类型的layoutParams,
//即必须使用GridLayout.LayoutParams
GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams();
layoutParams.setMargins(margin, margin, margin, margin);
layoutParams.height = GridLayout.LayoutParams.WRAP_CONTENT;
layoutParams.width = getResources().getDisplayMetrics().widthPixels / 4 - 2 * margin;
layoutParams.setMargins(margin, margin, margin, margin);
textView.setLayoutParams(layoutParams);
textView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
/**
* startDragAndDrop就是view的拖拽方法,他主要做了生成一个跟随鼠标拖动的控件视图。
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.startDragAndDrop(null, new View.DragShadowBuilder(v),
null, 0);
} else {
textView.startDrag(null, new View.DragShadowBuilder(v),
null, 0);
}
selectView = v;
selectView.setEnabled(false);
return false;
}
});
layout.addView(textView, 0);
}
}
···
layout布局文件:
···
<Button
android:id="@+id/btn"
android:text="添加"
android:onClick="addMyItem"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<GridLayout
android:columnCount="4"
android:animateLayoutChanges="true"
android:id="@+id/layout_myGrid"
android:layout_width="match_parent"
android:layout_height="wrap_content"></GridLayout>
···
布局文件很经典,没啥东西主要是设置gridlayout的列数,以及实现动画效果。
下面是textview的选择器:
···
<item android:state_enabled="true" android:drawable="@drawable/shape_tv_nor"/>
<item android:state_enabled="false" android:drawable="@drawable/shape_tv_sel"/>
···
选择器设置了textview的可不可用的背景,具体:@drawable/shape_tv_no的设置和@drawable/shape_tv_sel的设置是完全一样的,只是改了一下颜色,但是sel多了一个虚线,下面显示一个sel的代码:
···
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="5dp" />
<solid android:color="#ffffff" />
<stroke
android:width="1dp"
android:color="#f00"
android:dashGap="2dp"
android:dashWidth="1dp" />
</shape>
···