双击自定义视图打开 2 个活动

Double tap on custom view opens up 2 Activities

我的片段中几乎没有自定义六边形视图,双击六边形视图后,它会打开 2 个 Activties。我已经尝试了几种方法来避免这种行为,并且 none 似乎有效。不确定为什么以下内容不起作用。

我已经尝试了 post Android Preventing Double Click On A Button 中的所有方法,其中 none 对我的情况有效。我不确定在这种特定情况下有什么奇怪的。

我尝试的第一件事是将 Activties 启动模式设置为 "singleTop"。那没有用。所以我尝试了其他的,比如singleInstance,singleTask。

然后我尝试禁用单击六边形的视图并在 onResume 中启用它。 即使那样也行不通。单击时尝试保存最后一次单击时间。即使那样也没有用。

这是我的片段代码。

public class MenuFragment extends BaseFragment implements 
OnHexagonClickListener{
....
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_land_menu, container, false);
    ScrollView scroll_hexagon = view.findViewById(R.id.scroll_hexagon);
    isFirst = true;
    loadMenuData();
    scroll_hexagon.post(new Runnable() {
        @Override
        public void run() {
            int design_hexagon_width = getResources().getDimensionPixelSize(R.dimen.dimen_190dp);
            int design_hexagon_height = getResources().getDimensionPixelSize(R.dimen.dimen_160dp);
            int design_padding_horizontal = getResources().getDimensionPixelSize(R.dimen.dimen_5dp);
            int design_margin_horizontal = getResources().getDimensionPixelSize(R.dimen.dimen_3dp);
            int design_margin_vertical = getResources().getDimensionPixelSize(R.dimen.dimen_5dp);
            int design_margin_top = 0; //getResources().getDimensionPixelSize(R.dimen.dimen_5dp);

            int scroll_width = scroll_hexagon.getWidth();
            int hexagon_width = (int) (((scroll_width - design_padding_horizontal * 2) * 1.105f - design_margin_horizontal) / 2);
            int hexagon_margin_horizontal = hexagon_width - (int) ((scroll_width - design_padding_horizontal * 2) * 0.105f) + design_margin_horizontal;
            float scale = (float) hexagon_width / (float) design_hexagon_width;
            int hexagon_margin_vertical = ((int) (design_hexagon_height * scale) + design_margin_vertical) / 2;

            RelativeLayout hexagon_layout = view.findViewById(R.id.lyt_hexagon);
            for (int index = 0; index < mHexagonList.size(); index++) {
                Hexagon hexagon = mHexagonList.get(index);
                HexagonView hexagon_view = new HexagonView(activity, hexagon_width, hexagon_width);
                hexagon_view.setId(index);
                RelativeLayout.LayoutParams layoutparams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
                layoutparams.topMargin = design_margin_top + hexagon_margin_vertical * hexagon.getRowIndex();
                layoutparams.leftMargin = design_padding_horizontal + hexagon_margin_horizontal * hexagon.getColIndex();
                hexagon_view.setLayoutParams(layoutparams);
                hexagon_view.setData(hexagon.getType());
                hexagon_view.setOnHexagonClickListener(MenuFragment.this);
                hexagon_layout.addView(hexagon_view);
            }
            hexagon_layout.requestLayout();
        }
    });
    return view;
}

@Override
public void onClickHexagon(View view) {

    Hexagon hexagon = mHexagonList.get(view.getId());
    switch (hexagon.getType()) {
        case HexagonType.HEXAGON_PROFILE:
            startActivity(new Intent(activity, DashBoard.class));
            getActivity().overridePendingTransition(R.anim.anim_left_to_right, R.anim.anim_scale_out);
            break;
....
}

我的自定义视图代码:

public class HexagonView extends View implements Animation.AnimationListener {

private Paint mPaintBrush, mPaintText;
private LassoUtils mLassoUtils = null;
private List<PointF> mPointList = null;

private int mType;
private int mWidth, mHeight;
private int mWidthSpec, mHeightSpec;
private int mBackWidthSpec, mBackHeightSpec;
private int mThumbWidthSpec, mThumbHeightSpec, mThumbMarginSpec;
private int mIconWidthSpec, mIconHeightSpec, mIconMarginSpec;
private int mTextSize, mTextMarginSpec;

private String mText = "";

private Resources mResource;
private Bitmap mBackgroundBitmap = null;
private Bitmap mThumbBitmap = null;
private Bitmap mIconBitmap = null;
private OnHexagonClickListener mListener = null;
private Animation mAnim = null;

private boolean islasso = false;
private boolean isAnimating = false;

public HexagonView(Context context) {
    this(context, null);
}

public HexagonView(Context context, AttributeSet attr) {
    super(context, attr);
}

public HexagonView(Context context, int width, int height) {
    super(context, null);

    mType = HexagonType.HEXAGON_NONE;
    mResource = context.getResources();

    mWidthSpec = width;
    mHeightSpec = height;
    float scale = (float) width / (float) mResource.getDimensionPixelSize(R.dimen.dimen_190dp);
    mBackWidthSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_190dp) * scale);
    mBackHeightSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_160dp) * scale);
    mThumbWidthSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_185dp) * scale);
    mThumbHeightSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_171dp) * scale);
    mThumbMarginSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_10dp) * scale);
    mThumbMarginSpec = 0;
    mTextSize = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_12sp) * scale);
    mTextMarginSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_38dp) * scale);
    mIconWidthSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_46dp) * scale);
    mIconHeightSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_44dp) * scale);
    mIconMarginSpec = (int) (mResource.getDimensionPixelSize(R.dimen.dimen_3dp) * scale);

    int backColor = mResource.getColor(R.color.transparent);
    int textColor = mResource.getColor(R.color.color_text_white);

    mBackgroundBitmap = getBitmap(mResource.getDrawable(R.drawable.ic_wk_hexagon_bg), mBackWidthSpec, mBackHeightSpec);

    mPaintBrush = new Paint();
    mPaintBrush.setAntiAlias(true);
    mPaintBrush.setStyle(Paint.Style.FILL);
    mPaintBrush.setColor(backColor);

    mPaintText = new Paint();
    mPaintText.setAntiAlias(true);
    mPaintText.setTextSize(mTextSize);
    mPaintText.setStyle(Paint.Style.FILL);
    mPaintText.setTextAlign(Paint.Align.CENTER);
    mPaintText.setColor(textColor);

    mAnim = AnimationUtils.loadAnimation(context, R.anim.hexagon_click);
    mAnim.setAnimationListener(this);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(MeasureSpec.getSize(mWidthSpec), MeasureSpec.getSize(mHeightSpec));
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    mWidth = w;
    mHeight = h;
}

@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {

    if (mWidth == 0 || mHeight == 0)
        return;

    int lenght = mWidth / 2;
    double randian30 = 30 * Math.PI / 180;
    float a = (float) (lenght * Math.sin(randian30));
    float b = (float) (lenght * Math.cos(randian30));
    float c = (mHeight - 2 * b) / 2;

    Path path = new Path();
    path.moveTo(mWidth, mHeight / 2);
    path.lineTo(mWidth - a, mHeight - c);
    path.lineTo(mWidth - a - lenght, mHeight - c);
    path.lineTo(0, mHeight / 2);
    path.lineTo(a, c);
    path.lineTo(mWidth - a, c);
    path.close();

    canvas.drawPath(path, mPaintBrush);

    if (mBackgroundBitmap != null)
        canvas.drawBitmap(mBackgroundBitmap, (float) (mWidth / 2 - mBackWidthSpec / 2), (float) (mHeight / 2 - mBackHeightSpec / 2), null);

    if (mThumbBitmap != null)
        canvas.drawBitmap(mThumbBitmap, (float) (mWidth / 2 - mThumbWidthSpec / 2), (float) (mHeight / 2 - mThumbHeightSpec / 2 + mThumbMarginSpec), null);

    if (mIconBitmap != null)
        canvas.drawBitmap(mIconBitmap, (float) (mWidth / 2 - mIconWidthSpec / 2), (float) (mHeight / 2 - mIconHeightSpec + mIconMarginSpec), null);

    if (!mText.isEmpty())
        canvas.drawText(mText, (float) (mWidth / 2), (float) (mHeight / 2 + mTextSize + mTextMarginSpec), mPaintText);

    if (mPointList == null)
        mPointList = new ArrayList<>();
    else
        mPointList.clear();

    PointF pf = new PointF();
    pf.set(mWidth, mHeight / 2);
    mPointList.add(pf);
    PointF pf1 = new PointF();
    pf1.set(mWidth - a, mHeight - c);
    mPointList.add(pf1);
    PointF pf2 = new PointF();
    pf2.set(mWidth - a - lenght, mHeight - c);
    mPointList.add(pf2);
    PointF pf3 = new PointF();
    pf3.set(0, mHeight / 2);
    mPointList.add(pf3);
    PointF pf4 = new PointF();
    pf4.set(a, c);
    mPointList.add(pf4);
    PointF pf5 = new PointF();
    pf5.set(mWidth - a, c);
    mPointList.add(pf5);

    if (mLassoUtils == null)
        mLassoUtils = new LassoUtils();
    mLassoUtils.setLassoList(mPointList);
}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            islasso = mLassoUtils.contains(event.getX(), event.getY());
            break;
        case MotionEvent.ACTION_MOVE:
            islasso = mLassoUtils.contains(event.getX(), event.getY());
            break;
        case MotionEvent.ACTION_UP:
            if (isAnimating)
                break;

            if (mType == HexagonType.HEXAGON_NONE)
                break;

            this.startAnimation(mAnim);
            break;
    }
    return true;
}

@Override
public void onAnimationStart(Animation animation) {
    isAnimating = true;
}

@Override
public void onAnimationEnd(Animation animation) {
    if (islasso) {
        if (mListener != null)
            mListener.onClickHexagon(this);
    }
    islasso = false;
    isAnimating = false;
}

@Override
public void onAnimationRepeat(Animation animation) {

}

public void setData(int type) {

    mType = type;
    Drawable originThumbDrawable = null;
    Drawable originIconDrawable = null;

    switch (type) {
       case HexagonType.HEXAGON_PROFILE:
            originThumbDrawable = mResource.getDrawable(R.mipmap.land_hexagon_profile);
            originIconDrawable = mResource.getDrawable(R.mipmap.land_icon_profile);
            mText = mResource.getString(R.string.landing_profile);
            break;

        case HexagonType.HEXAGON_LEARNING:
            originThumbDrawable = mResource.getDrawable(R.mipmap.land_hexagon_learning);
            originIconDrawable = mResource.getDrawable(R.mipmap.land_icon_learning);
            mText = mResource.getString(R.string.landing_learning);
            break;

    }

    if (originThumbDrawable != null)
        mThumbBitmap = getBitmap(originThumbDrawable, mThumbWidthSpec, mThumbHeightSpec);

    if (originIconDrawable != null)
        mIconBitmap = getBitmap(originIconDrawable, mIconWidthSpec, mIconHeightSpec);
}

public void setOnHexagonClickListener(OnHexagonClickListener listener) {
    this.mListener = listener;
}

private Bitmap getBitmap(Drawable drawable, int width, int height) {
    Canvas canvas = new Canvas();
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    canvas.setBitmap(bitmap);
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    drawable.draw(canvas);
    return Bitmap.createScaledBitmap(bitmap, width, height, false);
}

}

这是最好的 hack,双击发生在不到一秒钟内,您可以在第一次单击后的一秒钟内禁用单击。在 class

上添加一个全局变量
public static boolean clickable = true;

点击时切换它,效果很好

    if (!clickable){
        return;
    }
    clickable = false;
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            clickable = true;
        }
    }, 1000);
    //continue with your click code
public boolean clickable = true;

@Override
public void onAnimationEnd(Animation animation) {
    if (islasso) {
        if (mListener != null && clickable) {
            clickable = false;
            mListener.onClickHexagon(this);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    clickable = true;
                }
            }, 1500);
        }
    }
    islasso = false;
    isAnimating = false;
}

试试这个