0

XMLレイアウトからレイアウトをロードし、独自のXML属性を実装する簡単な複合コントロールを追加しました。

ただし、これは、このコントロールがメインパッケージ(com.myapp)にある場合にのみ機能します。com.myapp.controls物事が失敗し始めるように、それをサブパッケージに移動しようとすると。

これは、コントロールのカスタム属性を定義するattrs.xmlです。

<resources>

    <declare-styleable name="CH2">
        <attr name="textText" format="string" />
    </declare-styleable>

    <declare-styleable name="CH3">
        <attr name="textFex" format="string" />
    </declare-styleable>

</resources>

これは、サブパッケージに含まれ、機能しないコントロールCH2.javaです。

package com.myapp.controls;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

public class CH2 extends LinearLayout {

    private TextView textView;

    public CH2(Context context) throws Exception {
        super(context);
        init(context, null);
    }

    public CH2(Context context, AttributeSet attrs) throws Exception {
        super(context, attrs);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) throws Exception {

        this.setOrientation(LinearLayout.VERTICAL);

        LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        layoutInflater.inflate(com.myapp.R.layout.category_header, this, true);

        View v = findViewById(com.myapp.R.id.chText);
        this.textView = (TextView)v;

        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, com.myapp.R.styleable.CH2);

            String text = a.getString(com.myapp.R.styleable.CH2_textText);
            this.textView.setText(text != null ? text : "<NULL!>");

            a.recycle();        
        }
    }
}

これは動作するCH3.javaです:

package com.myapp;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

public class CH3 extends LinearLayout {

    private TextView textView;

    public CH3(Context context) throws Exception {
        super(context);
        init(context, null);
    }

    public CH3(Context context, AttributeSet attrs) throws Exception {
        super(context, attrs);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) throws Exception {

        this.setOrientation(LinearLayout.VERTICAL);

        LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        layoutInflater.inflate(com.myapp.R.layout.category_header, this, true);

        View v = findViewById(com.myapp.R.id.chText);
        this.textView = (TextView)v;

        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, com.myapp.R.styleable.CH3);

            String text = a.getString(com.myapp.R.styleable.CH3_textFex);
            this.textView.setText(text != null ? text : "<NULL!>");

            a.recycle();        
        }
    }
}

両方のソースは同じcategory_header.xmlを使用します。レイアウトは問題なくロードされます。私はこのように両方を使うことができます:

<com.myapp.controls.CH2
    android:id="@+id/cH1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
    myns:textText="Test 1" >
</com.myapp.controls.CH2>

<com.myapp.CH3
    android:id="@+id/cH2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    myns:textFex="Test 2"
    >
</com.myapp.CH3>

CH2を機能させるにはどうすればよいですか?または、別のパッケージを使用することは不可能ですか?

サイドクエスト:両方のコントロールで同じXML属性を使用することはできますtextTextか、それとも常に異なる属性を使用する必要がありますか?または、宣言可能なスタイルの名前をコンポーネントの名前と異なるようにすることはできますか?


新しいdeclare-styleableを使用した別のアプローチ:

<declare-styleable name="controls.CH2">
    <attr name="textText" format="string" />
</declare-styleable>

しかし、それは使用できないようです。XMLビューには、CH2の使用方法に関係なく、レイアウトファイルで予期しないテキストが見つかりましたと常に表示されます。

xmlns:myns="http://schemas.android.com/apk/res/com.myapp"
xmlns:mynsc="http://schemas.android.com/apk/res/com.myapp.controls"
...
<com.myapp.controls.CH2
    android:id="@+id/cH1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
    mynsc:textText="TestTestTest" 
    >        
</com.myapp.controls.CH2>

また

xmlns:myns="http://schemas.android.com/apk/res/com.myapp"
...
<com.myapp.controls.CH2
    android:id="@+id/cH1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
    myns.controls:textText="TestTestTest" 
    >        
</com.myapp.controls.CH2>
4

1 に答える 1

1

自分の属性ファイルに戻りましたが、レイアウトが存在する非常に深いサブパッケージへの参照はどこにもありません...補足として、attrsファイルでこれを行うと、複数の要素に同じ属性を使用させることができます:

<resources>
    <attr name="textText" format="string"/>

    <declare-styleable name="CH2">
        <attr name="textText" />
    </declare-styleable>

    <declare-styleable name="CH3">
        <attr name="textText" />
    </declare-styleable>

</resources>

私のAndroidソースコードの調査では、あなたが説明していることを正確に実行するいくつかの例が示されています。ここでは、異なるパッケージのビュークラスを指す単一のカスタム属性ファイルがあります。私が見た唯一の明らかな違いは、ビューが次のようにレイアウトで宣言されていたことです。

<view
  class="com.myapp.controls.CH2"
  android:id="@+id/cH1"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" >
  myns:textText="Test 1" >
</view>

<view
  class="com.myapp.CH3"
  android:id="@+id/cH2"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" 
  myns:textFex="Test 2"
>
</view>

正直なところ、なぜそれが違いを生むのかはわかりません...しかし、使用される形式であるカスタム属性が必要になるたびに

于 2012-04-05T17:01:19.570 に答える