diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java index 2450a80a..93956613 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java @@ -37,6 +37,7 @@ import com.keylesspalace.tusky.util.LinkHelper; import com.keylesspalace.tusky.util.StatusDisplayOptions; import com.keylesspalace.tusky.util.ThemeUtils; import com.keylesspalace.tusky.util.TimestampUtils; +import com.keylesspalace.tusky.util.ViewExtensionsKt; import com.keylesspalace.tusky.view.MediaPreviewImageView; import com.keylesspalace.tusky.viewdata.PollOptionViewData; import com.keylesspalace.tusky.viewdata.PollViewData; @@ -111,7 +112,16 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder { favouriteButton = itemView.findViewById(R.id.status_favourite); bookmarkButton = itemView.findViewById(R.id.status_bookmark); moreButton = itemView.findViewById(R.id.status_more); + + float INCREASE_HORIZONTAL_HIT_AREA = 20.0f; + ViewExtensionsKt.increaseHitArea(replyButton, 0.0f, INCREASE_HORIZONTAL_HIT_AREA); + if(reblogButton != null) + ViewExtensionsKt.increaseHitArea(reblogButton, 0.0f, INCREASE_HORIZONTAL_HIT_AREA); + ViewExtensionsKt.increaseHitArea(favouriteButton, 0.0f, INCREASE_HORIZONTAL_HIT_AREA); + ViewExtensionsKt.increaseHitArea(bookmarkButton, 0.0f, INCREASE_HORIZONTAL_HIT_AREA); + ViewExtensionsKt.increaseHitArea(moreButton, 0.0f, INCREASE_HORIZONTAL_HIT_AREA); + itemView.findViewById(R.id.status_media_preview_container).setClipToOutline(true); mediaPreviews = new MediaPreviewImageView[]{ @@ -632,6 +642,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder { listener.onMore(v, position); } }); + /* Even though the content TextView is a child of the container, it won't respond to clicks * if it contains URLSpans without also setting its listener. The surrounding spans will * just eat the clicks instead of deferring to the parent listener, but WILL respond to a diff --git a/app/src/main/java/com/keylesspalace/tusky/util/ViewExtensions.kt b/app/src/main/java/com/keylesspalace/tusky/util/ViewExtensions.kt index 389995ae..ae9a8859 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/ViewExtensions.kt +++ b/app/src/main/java/com/keylesspalace/tusky/util/ViewExtensions.kt @@ -20,6 +20,13 @@ import android.text.Editable import android.text.TextWatcher import android.view.View import android.widget.EditText +import android.util.TypedValue +import android.content.res.Resources +import android.view.TouchDelegate +import android.view.MotionEvent +import android.graphics.Rect +/*import java.util.List +import java.util.ArrayList*/ fun View.show() { this.visibility = View.VISIBLE @@ -33,6 +40,51 @@ fun View.visible(visible: Boolean, or: Int = View.GONE) { this.visibility = if (visible) View.VISIBLE else or } +class MultipleTouchDelegate : TouchDelegate { + + var delegates = mutableListOf() + + constructor(v: View) : super(Rect(), v) + + public fun addDelegate(delegate: TouchDelegate) { + delegates.add(delegate) + } + + override fun onTouchEvent(event: MotionEvent) : Boolean { + var ret = false + val x = event.x + val y = event.y + + for(delegate in delegates) { + event.setLocation(x, y) + ret = delegate.onTouchEvent(event) || ret + } + + return ret + } +} + +fun View.increaseHitArea(vdp: Float, hdp: Float) { + val parent = this.parent as View + val vpixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, vdp, Resources.getSystem().displayMetrics).toInt() + val hpixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, hdp, Resources.getSystem().displayMetrics).toInt() + parent.post { + val rect = Rect() + this.getHitRect(rect) + rect.top -= vpixels + rect.left -= hpixels + rect.bottom += vpixels + rect.right += hpixels + if(parent.touchDelegate != null && parent.touchDelegate is MultipleTouchDelegate) { + (parent.touchDelegate as MultipleTouchDelegate).addDelegate(TouchDelegate(rect, this)) + } else { + val mtd = MultipleTouchDelegate(this) + mtd.addDelegate(TouchDelegate(rect, this)) + parent.touchDelegate = mtd + } + } +} + open class DefaultTextWatcher : TextWatcher { override fun afterTextChanged(s: Editable) { } @@ -60,4 +112,4 @@ inline fun EditText.afterTextChanged( callback(s) } }) -} \ No newline at end of file +}