Android自定义GridLayout实现标签脱拉拽

这篇博客展示了如何在Android中实现一个自定义的GridLayout,支持用户通过拖拽操作来调整标签的位置,提供了实现这一功能的MainActivity的XML布局和自定义类MyGridLayout的详细说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图:

1. MianActivity:

package com.example.mytuolazhuai;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;

import java.util.ArrayList;
import java.util.List;

//自定义view托拉拽
public class MainActivity extends AppCompatActivity {
    private MyGridLayout my_gridLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        my_gridLayout = (MyGridLayout) findViewById(R.id.my_gridLayout);
        my_gridLayout.setIsDragabled(true);

        List<String> list = new ArrayList<>();
        list.add("新闻");
        list.add("百度");
        list.add("新浪");
        list.add("电影");
        list.add("动画");
        list.add("科技");
        list.add("科技");
        list.add("娱乐");
        list.add("军事");
        list.add("政治");
        list.add("语文");
        list.add("综艺");
        my_gridLayout.addItem(list);


    }
}

MainActivity的xml布局:
 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.example.mytuolazhuai.MyGridLayout
        android:layout_marginTop="15dp"
        android:id="@+id/my_gridLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></com.example.mytuolazhuai.MyGridLayout>

</LinearLayout>

2.自定义类MyGridLayout:

package com.example.mytuolazhuai;

import android.animation.LayoutTransition;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.DragEvent;
import android.view.Gravity;
import android.view.View;
import android.widget.GridLayout;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.List;

public class MyGridLayout extends GridLayout {
    public MyGridLayout(Context context) {
        this(context, null);
    }

    public MyGridLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyGridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setColumnCount(4);
       setLayoutTransition(new LayoutTransition());
    }


    public void addItem(List<String> strList) {
        for (String str : strList) {
            setTextItems(str);
        }
    }

    //添加GridLayout里面的textView
    int mMag = 10;
    private View mDragView;

    public void setTextItems(String str) {
        TextView textView = new TextView(getContext());
        textView.setText(str);//添加文字
        textView.setBackgroundResource(R.drawable.shape);

        int tv_width = getResources().getDisplayMetrics().widthPixels / getColumnCount() - mMag * 2;//获取屏幕宽/列数
        textView.setWidth(tv_width);

        textView.setGravity(Gravity.CENTER);//文字居中

        //   textView.setSingleLine();//将文字设置成一行

        //跑马灯效果
        textView.setFocusable(true);
        textView.setFocusableInTouchMode(true);
        textView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
        textView.setMarqueeRepeatLimit(-1);

        //控件和控件间隔10dp
        GridLayout.LayoutParams params = new LayoutParams();
        params.setMargins(mMag, mMag, mMag, mMag);
        textView.setLayoutParams(params);

        addView(textView);

        textView.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                mDragView = v;
                v.startDrag(null, new DragShadowBuilder(v), null, 0);
                return true;
            }
        });

    }

    public void setIsDragabled(boolean falg) {
        if (falg) {
            //设置监听器
            setOnDragListener(dragListener);
        } else {
            setOnDragListener(null);
        }


    }

    private OnDragListener dragListener = new OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                    initRects();

                    break;

                //实时就监听a标签是否处于b标签的范围内
                case DragEvent.ACTION_DRAG_LOCATION:
                    int index = getIndex(event);
                    if (index > -1 && mDragView != null && mDragView != getChildAt(index)) {
                        removeView(mDragView);
                        addView(mDragView, index);


                    }
                    break;
                case DragEvent.ACTION_DRAG_ENDED:
                    break;


                case DragEvent.ACTION_DRAG_EXITED:
                    break;
                case DragEvent.ACTION_DRAG_ENTERED:
                    break;
                case DragEvent.ACTION_DROP:
                    break;
            }
            return true;
        }


    };

    //i 被脱拉拽到的那个标签对应的索引值
    private int getIndex(DragEvent event) {
        for (int i = 0; i < mRectArr.length; i++) {
            float x = event.getX();
            float y = event.getY();
            if (mRectArr[i].contains((int) x, (int) y)) {
                return i;
            }
        }

        //在其他范围
        return -1;
    }

    private Rect[] mRectArr;

    private void initRects() {

        int childCount = getChildCount();
        mRectArr = new Rect[childCount];

        for (int i = 0; i < childCount; i++) {

            View view = getChildAt(i);//根据每个条目的i
            Rect rect = new Rect(view.getLeft(), view.getTop()
                    , view.getRight(), view.getBottom());
            mRectArr[i] = rect;
        }
    }

}
以上代码就实现了上图的效果啦

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值