android-TextView的长按复制

引子

android很多app都支持文本的选中,复制。根据观察,主要分为两类:

1)自由复制(弹出框里面支持全选)

2)仅支持全选复制

今天工作中遇到了全选的需求,现总结出来,方便以后查阅.

 

 

自由复制

这种方式很简单,只需要两行代码,(下面的红色)

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="长按自由复制"
        android:textColorHighlight="#CCCCCC"
        android:textIsSelectable="true" />

 

运行起来;

长按这个TextView,就会出现系统自带的弹出框。

如图:

 

 

自定义dialog全选复制

针对这个功能,我写了一个工具类,现在贴出主要代码:

3个java类:

package com.example.longpresscopy;

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

public class MainActivity extends AppCompatActivity {

    private TextView tv_test, tv_test2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);// 隐藏标题
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏
        setContentView(R.layout.activity_main);
        tv_test = findViewById(R.id.tv_test);
        tv_test2 = findViewById(R.id.tv_test2);

        new CopyShowerUtil(this, tv_test);
        new CopyShowerUtil(this, tv_test2);
    }


}

 

import android.app.Dialog;
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import com.gwtsz.gts2.hx.R;

/**
 * 生成一个始终跟随 参数控件的窗口
 */
public class CopyDialog extends Dialog {

    public CopyDialog(@NonNull Context context, View layout, View tv_relative) {
        super(context, R.style.copyDialog);
        setContentView(layout);
        Window window = getWindow();
        WindowManager.LayoutParams params = window.getAttributes();
        params.gravity = Gravity.TOP | Gravity.LEFT;// dialog的初始位置为左上角

        Rect r = new Rect();
        tv_relative.getGlobalVisibleRect(r);

        params.x = r.left + (r.right - r.left) / 2;//X轴上平移,直到X轴的值,在tv_relative的中心线
        params.y = r.top + (r.bottom - r.top) / 2;
        window.setAttributes(params);
    }

}

 

import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

public class CopyShowerUtil {

    private Context mContext;
    private TextView tv_test;

    private int originalColor = 0xFFFFFFFF;
    private int highLightColor = 0xFFCCCCCC;

    public void setOriginalColor(int originalColor) {
        this.originalColor = originalColor;
    }

    public void setHighLightColor(int highLightColor) {
        this.highLightColor = highLightColor;
    }

    /**
     * 执行
     *
     * @param context
     * @param tv_test_T
     */
    public CopyShowerUtil(Context context, TextView tv_test_T) {
        mContext = context;
        tv_test = tv_test_T;
        tv_test.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                gotoCopyState();
                return false;
            }
        });
    }

    private boolean ifCopyState = false;

    private void gotoCopyState() {
        if (!ifCopyState) {
            tv_test.setBackgroundColor(highLightColor);
            View layout = LayoutInflater.from(mContext).inflate(R.layout.tv_corner_copy, null);
            final CopyDialog copyDialog = new CopyDialog(mContext, layout, tv_test);
            layout.setOnClickListener(new View.OnClickListener() {
                @SuppressLint("NewApi")
                @Override
                public void onClick(View v) {
                    ClipboardManager manager = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
                    manager.setPrimaryClip(ClipData.newHtmlText(null, tv_test.getText().toString(), null));
                    copyDialog.dismiss();
                    copyDialog.cancel();
                }
            });
            copyDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    leaveCopyState();
                }
            });
            copyDialog.show();
            ifCopyState = true;
        }
    }

    private void leaveCopyState() {
        if (ifCopyState) {
            tv_test.setBackgroundColor(originalColor);
            ifCopyState = false;
        }
    }
}

 

layout目录里的布局文件:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/ll_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical"
    android:paddingLeft="10dp"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="长按自由复制"
        android:textColorHighlight="#CCCCCC"
        android:textIsSelectable="true" />

    <TextView
        android:id="@+id/tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="Hello World!难道真的可以复制???" />

    <TextView
        android:id="@+id/tv_test2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:maxEms="10"
        android:text="试试第二个?难道真的可以复制?阿什顿飞撒地方士大夫士大夫士大夫士大夫撒旦撒大幅度的萨芬答复" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:hint="放在这里" />

</LinearLayout>

tv_corner_copy.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_copy"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@drawable/tv_copy_corner"
    android:gravity="center"
    android:paddingBottom="5dp"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:paddingTop="5dp"
    android:text="复制" />

 

drawable目录里面的sharp.xml文件

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <stroke
        android:width="1dp"
        android:color="#bbbbbb" />
    <corners android:radius="2dp" />
</shape>

 要加入到styles.xml里面的 dialog风格

<style name="copyDialog" parent="@android:style/Theme.Dialog">
        <item name="android:windowFrame">@null</item><!--边框-->
        <item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
        <item name="android:windowIsTranslucent">false</item><!--半透明-->
        <item name="android:windowNoTitle">true</item><!--无标题-->
        <item name="android:windowBackground">@color/transparent</item><!--背景透明-->
        <item name="android:backgroundDimEnabled">false</item><!--模糊-->
    </style>

以及color

<color name="background_white">#FFFFFF</color>

最终效果

 

可以点复制,然后在下面的EditText里面粘贴。

 

 

弹出框会始终跟随要复制的内容。

 

posted @ 2018-06-20 18:34  波澜不惊x  阅读(7157)  评论(0编辑  收藏  举报