2012-04-05 4 views
0

Ich habe eine einfache Verbindung Kontrolle hinzugefügt, die das Layout von einem XML-Layout geladen und implementiert eigene XML-Attribute.Verbindung control in anderem Paket

Das funktioniert aber nur, während diese Steuerung in dem Hauptpaket ist (com.myapp). Wenn ich versuche, es in ein Unterpaket wie com.myapp.controls zu verschieben, beginnen die Dinge zu versagen.

Dies ist die attrs.xml die Steuerung individuelle zu definieren Attribute:

<resources> 

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

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

</resources> 

Dies ist die Kontrolle, die in CH2.java subspackage ia und tut nicht Arbeit:

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();   
     } 
    } 
} 

Diese ist CH3.java, die funktioniert:

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();   
     } 
    } 
} 

Beide Quellen verwenden die gleiche category_header.xml. Das Layout wird ohne Probleme geladen. Ich kann beide so verwenden:

<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> 

Wie kann ich CH2 arbeiten lassen? Oder ist es unmöglich, ein anderes Paket zu verwenden?

Sidequest: Kann ich beide Steuerelemente verwenden, um das gleiche XML-Attribut textText zu verwenden, oder müssen sie immer unterschiedliche Attribute verwenden? Oder kann sich der Name des deklarierbaren Stils vom Komponentennamen unterscheiden?


Ein anderer Ansatz mit einem neuen declare-styleable:

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

Aber es scheint nicht verwendbar zu sein. XML-Ansicht sagt immer Unerwarteter Text in der Layout-Datei gefunden:, unabhängig davon, wie ich 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> 

oder

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> 
+1

Was war der Fehler, wenn Sie versucht, es die erste Art und Weise zu tun? nur, dass der Parameter nicht übergeben bekommen? – JRaymond

+0

Sie haben Recht, das funktioniert. Es war einfach nicht zuerst, weil es einen XML-Fehler gab (unerkannt von Eclipse). Das funktioniert also perfekt! Ich musste nur das Projekt säubern und Eclipse neu starten, um alle Namespace-Änderungen wirksam werden zu lassen. – ZoolWay

Antwort

1

Ich ging zurück zu meinen eigenen Attributdateien und es gibt keinen Hinweis überall das sehr tiefe Unterpaket, in dem mein Layout lebt ... Als Randnotiz können Sie mehrere Elemente verwenden, die dasselbe Attribut verwenden, wenn Sie dies in Ihrer attrs-Datei tun:

<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> 

Meine Studie des Android-Quellcodes zeigt ein paar Beispiele, wo sie genau das tun, was Sie beschreiben, wo sie eine einzige benutzerdefinierte Attributdatei haben, die auf Klassen in verschiedenen Paketen zeigt. Der einzige eklatante Unterschied war ich sah, dass die Ansichten wie diese in dem Layout erklärt wurden:

<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> 

Ich konnte wirklich nicht sagen, warum das einen Unterschied machen würde ... aber jedes Mal, wenn sie benötigen benutzerdefinierte Attribute, die sind Format verwendet

+0

Dies funktioniert nicht, die XML-Ansicht sagt immer noch "Unerwarteter Text gefunden in Layout-Datei: myns: textText ..." – ZoolWay

+0

@ZoolWay Ich nehme an, Sie haben Ihren Namespace und das Schema oben im Layout deklariert? – JRaymond

+0

Ich habe die Frage bearbeitet, wie ich versucht habe, es zu benutzen. – ZoolWay