androidandroid-activityviewlaunchmode

Double tap on custom view opens up 2 Activities


I have few custom hexagon views in my fragment and upon double tapping on hexagon view,it opens up 2 Activties. I have tried several things to avoid this behaviour and none of it seems to work. Not sure why following things are not working.

I have tried all the things in this post Android Preventing Double Click On A Button and none of them is working in my case. I am not sure what is so weird in this specific case.

First thing i have tried is, by making Activties launch mode set to "singleTop". That didn't work. So i tried others such as singleInstance, singleTask.

Then i tried to disable view on click of hexagon and enable it in onResume. Even that didnt work. Tried saving a last click time when clicking. Even that didnt work.

Here is my code in fragment.

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;
....
}

Code for my custom view :

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);
}

}


Solution

  • 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;
    }
    

    try this