Android片段中的自定义属性

Ant*_*ton 33 android custom-attributes fragment android-fragments

我想在Android片段中使用XML定义自定义属性(不使用捆绑其他参数),就像declare-styleable在自定义控件中一样.但是没有带有AttrSet参数的构造函数,所以它可能吗?我可以覆盖public void onInflate(android.app.Activity activity, android.util.AttributeSet attrs, android.os.Bundle savedInstanceState)以获得属性支持吗?

Jav*_*tor 81

支持4Demos的链接已更改或可以更改,因此发布完整的解决方案.在这里.

  1. 在res/values文件夹中创建attrs.xml文件.如果文件已存在,请添加以下内容.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <declare-styleable name="MyFragment">
        <attr name="my_string" format="string"/>
        <attr name="my_integer" format="integer"/>
    </declare-styleable> 
    
    Run Code Online (Sandbox Code Playgroud)

  2. 覆盖片段的onInflate委托并读取其中的属性

    /**
     * Parse attributes during inflation from a view hierarchy into the
     * arguments we handle.
     */
    @Override
    public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
        super.onInflate(activity, attrs, savedInstanceState);
        Log.v(TAG,"onInflate called");
    
        TypedArray a = activity.obtainStyledAttributes(attrs,R.styleable.MyFragment);
    
        CharSequence myString = a.getText(R.styleable.MyFragment_my_string);
        if(myString != null) {
            Log.v(TAG, "My String Received : " + myString.toString());
        }
    
        int myInteger = a.getInt(R.styleable.AdFragment_my_integer, -1);
        if(myInteger != -1) {
            Log.v(TAG,"My Integer Received :" + myInteger);
        }
    
        a.recycle();
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在布局文件中传递这些属性,如下所示.只是一个例子

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="This is android activity" />
    
        <fragment
            android:id="@+id/ad_fragment"
            android:name="com.yourapp.packagename.MyFragment"
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true"
            app:my_string="Hello This is HardCoded String. Don't use me"
            app:my_integer="30" />
    
    </RelativeLayout>
    
    Run Code Online (Sandbox Code Playgroud)

就这样.这是一个有效的解决方

如果您在xml中看到任何名称空间错误,请执行此操作.一次又一次地尝试清洁项目.这是可悲的,但有时候是日食和adt行为不端.

希望它能帮助别人:)

干杯

  • 我的Android Studio一直在显示XML中的自定义属性,红色下划线表示存在错误,但整个项目构建得很好.对于那些可能认为他们没有正确查看布局文件中的错误的人来说. (2认同)
  • 您可以使用 `http://schemas.android.com/apk/res-auto` 而不是 xmlns:app="http://schemas.android.com/apk/res/com.yourapp.packagename" 来自动替换包名。http://stackoverflow.com/questions/10448006/xml-namespace-declaration-auto-substitute-package-name (2认同)
  • Android Studio 显示 `onInflate(Activity activity ...` 已弃用。您可以使用这样的新处理程序 (Kotlin):`override fun onInflate(context: Context?, attrs: AttributeSet?, savedInstanceState: Bundle?) { super. onInflate(context, attrs, savedInstanceState) val styledAttributes = context?.obtainStyledAttributes(attrs, R.styleable.MyFragment_my_string) val text = styledAttributes?.getText(R.styleable.MyFragment_my_string) styledAttributes?.recycle() }` (2认同)

the*_*ike 1

@Override
public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
    super.onInflate(activity, attrs, savedInstanceState); 
    // Your code here to process the attributes
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢 tdevaux,我只花了 5 分钟就重读了这篇文章。我的人生还有5分钟! (3认同)
  • 有效,但请确保清除 Lint 标记(Android 工具 &gt; 清除 Lint 标记)。我花了 1000 万试图找出为什么它没有构建! (2认同)