Long press definition at XML layout, like android:onClick does
There is any way to define into XML layout longKeyLongPress definition like onClick does ?.
i.e this is my view
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:text="Line 1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/message"
android:textSize="15dip"
android:textStyle="bold"
android:textColor="@color/colorblue"
android:shadowDy="1.0"
android:shadowDx="1.0"
android:shadowRadius="1开发者_StackOverflow中文版.0"
android:shadowColor="#ffffffff"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="5dip"
android:lineSpacingExtra="3dip"
android:lineSpacingMultiplier="1.1"
android:singleLine="false"
android:autoLink="web|email|phone|map|all"
android:onClick="clickHandler"
android:clickable="true"
/>
I want something like before but reacting to longpress event.
Note:
I don't want to add listener from my code.
I tried with android:longClickable.
The attribute is not defined, however you can implement it.
- Extend TextView and let's call it MyTextView.
Then add file attrs.xml in res/values/ with following content:
<xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyTextView"> <attr name="onKeyLongPress" format="string"/> </declare-styleable> </resources>
In MyTextView constructor add logic to read data from xml:
public MyTextView(final Context context, final AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyTextView); for (int i = 0; i < a.getIndexCount(); ++i) { int attr = a.getIndex(i); switch (attr) { case R.styleable.MyTextView_onKeyLongPress: { if (context.isRestricted()) { throw new IllegalStateException("The "+getClass().getCanonicalName()+":onKeyLongPress attribute cannot " + "be used within a restricted context"); } final String handlerName = a.getString(attr); if (handlerName != null) { setOnLongClickListener(new OnLongClickListener() { private Method mHandler; @Override public boolean onLongClick(final View p_v) { boolean result = false; if (mHandler == null) { try { mHandler = getContext().getClass().getMethod(handlerName, View.class); } catch (NoSuchMethodException e) { int id = getId(); String idText = id == NO_ID ? "" : " with id '" + getContext().getResources().getResourceEntryName( id) + "'"; throw new IllegalStateException("Could not find a method " + handlerName + "(View) in the activity " + getContext().getClass() + " for onKeyLongPress handler" + " on view " + MyTextView.this.getClass() + idText, e); } } try { mHandler.invoke(getContext(), MyTextView.this); result = true; } catch (IllegalAccessException e) { throw new IllegalStateException("Could not execute non " + "public method of the activity", e); } catch (InvocationTargetException e) { throw new IllegalStateException("Could not execute " + "method of the activity", e); } return result; } }); } break; } default: break; } } a.recycle(); }
Use new attribute in your layout xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/res-auto" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <your.package.MyTextView android:id="@+id/theId" android:layout_width="wrap_content" android:layout_height="wrap_content" custom:onKeyLongPress="myDoSomething" /> <!-- Other stuff --> </LinearLayout>
Credits:
- I have learned how to do this from this post: http://kevindion.com/2011/01/custom-xml-attributes-for-android-widgets/
- Snippet for constructor with slight modifications was taken from original android View class.
Looking at the current documentation, such an XML parameter does not currently exist. The longClickable is a boolean parameter to define simply whether a View is responds to long clicks or not.
(10 years later, might be useful to others)
When using Databinding and MVVM you can write a Bindingadapter that works as intended:
@BindingAdapter("android:onLongClick")
fun setOnLongClickListener(view: View,block : () -> Unit) {
view.setOnLongClickListener {
block()
return@setOnLongClickListener true
}
}
You can then use it like: android:onLongClick="@{() -> vm.yourFunction()}"
You can also return the function and change Unit to boolean if you indend to return false in some cases
精彩评论