laobie / SelectableTextHelper

Set selectable for TextView.
https://jaeger.itscoder.com/android/2016/11/21/selectable-text-helper.html
361 stars 59 forks source link

对于页面内有多个textview需要使用到该help出现的长按多个textview会出现多个helper弹框问题 #8

Open xiaoting000 opened 6 years ago

xiaoting000 commented 6 years ago

我的解决办法: 在 helper内用个static isShowing 来标记是否已经有复制弹出pop显示, 再用一个static storedHelper存放当前显示的helper, 然后再show 和 hide方法里对标记和 对storedHelper做清理操作, 具体添加代码如下:

private static boolean isShowing = false;
private static SelectableTextHelper storedHelper;

public void hideSelectView() {
        isShowing = false;
//your code
//......
}

private void showSelectView(int x, int y) {
        if(isShowing){
            storedHelper.resetStored();
        }
// your code
//.....
}

public void resetStored(){
        resetSelectionInfo();
        hideSelectView();
        mStartHandle = null;
        mEndHandle = null;
        mOperateWindow = null;
    }

 

xiaoting000 commented 6 years ago

showSelectView 方法最后少贴了一行:

private void showSelectView(int x, int y) {
if(isShowing){
storedHelper.resetStored();
}
// your code start
//.....
//your code end

storedHelper = this;

}
laobie commented 6 years ago

这样是可以解决的,目前这个项目处在一个探索的过程,其实实际应用到项目中还是需要很多处理的

as2227024221 commented 5 years ago

showSelectView 方法最后少贴了一行:

private void showSelectView(int x, int y) {
if(isShowing){
storedHelper.resetStored();
}
// your code start
//.....
//your code end

storedHelper = this;

}

我试了好像不行啊

liwuchen commented 5 years ago

我的解决办法: 在 helper内用个static isShowing 来标记是否已经有复制弹出pop显示, 再用一个static storedHelper存放当前显示的helper, 然后再show 和 hide方法里对标记和 对storedHelper做清理操作, 具体添加代码如下:

private static boolean isShowing = false;
private static SelectableTextHelper storedHelper;

public void hideSelectView() {
        isShowing = false;
//your code
//......
}

private void showSelectView(int x, int y) {
        if(isShowing){
            storedHelper.resetStored();
        }
// your code
//.....
}

public void resetStored(){
        resetSelectionInfo();
        hideSelectView();
        mStartHandle = null;
        mEndHandle = null;
        mOperateWindow = null;
    }

少了把isShowing设为true的步骤, 另外你这里没有判断两次长按的对象是不是同一个,如果是同一个的话,当前mOperateWindow 设为null了就会出错。

xiaoting000 commented 5 years ago

showSelectView 方法最后少贴了一行:

private void showSelectView(int x, int y) {
if(isShowing){
storedHelper.resetStored();
}
// your code start
//.....
//your code end

storedHelper = this;

}

我试了好像不行啊

我这边是可以的,

我的解决办法: 在 helper内用个static isShowing 来标记是否已经有复制弹出pop显示, 再用一个static storedHelper存放当前显示的helper, 然后再show 和 hide方法里对标记和 对storedHelper做清理操作, 具体添加代码如下:

private static boolean isShowing = false;
private static SelectableTextHelper storedHelper;

public void hideSelectView() {
        isShowing = false;
//your code
//......
}

private void showSelectView(int x, int y) {
        if(isShowing){
            storedHelper.resetStored();
        }
// your code
//.....
}

public void resetStored(){
        resetSelectionInfo();
        hideSelectView();
        mStartHandle = null;
        mEndHandle = null;
        mOperateWindow = null;
    }

少了把isShowing设为true的步骤, 另外你这里没有判断两次长按的对象是不是同一个,如果是同一个的话,当前mOperateWindow 设为null了就会出错。

isShowing置为true 在的if(isShowing){ storedHelper.resetStored(); }

之后有置为true, 忘了贴上来了, mOperateWindow 使用有判空的,同一个对象选择是没有问题的我这边现在也是正常使用,你那边如果有具体的问题可以贴上来看看

xiaoting000 commented 5 years ago

使用方法:new SelectableTextHelper(tvTestContent); 贴上修改之后的完整SelectableTextHelper代码: package com.snda.mcommon.util.selecttext; import android.annotation.SuppressLint; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Build; import android.text.Layout; import android.text.Spannable; import android.text.Spanned; import android.text.method.MovementMethod; import android.text.style.BackgroundColorSpan; import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.PopupWindow; import android.widget.TextView; import com.snda.mcommon.R; /**

taotaodai commented 4 years ago

我的办法是去监听Activity中的dispatchTouchEvent方法。因为游标和操作弹框都是用PopupWindow,PopupWindow里的控件会消费掉触摸事件,不会传递到父控件,所以当dispatchTouchEvent被响应时,说明我点击到了外部区域,这时把游标、弹框以及背景都清空就好了

djxf commented 4 years ago

还行。