开发者

Long press definition at XML layout, like android:onClick does

开发者 https://www.devze.com 2023-02-27 00:23 出处:网络
There is any way to define into XML layout longKeyLongPress definition like onClick does ?. i.e this is my view

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.

  1. Extend TextView and let's call it MyTextView.
  2. 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>
    
  3. 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();
    
    }
    
  4. 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

0

精彩评论

暂无评论...
验证码 换一张
取 消