2012-07-22 8 views
5

Sto provando a configurare un TextSwitcher con TextView che carica da un file xml. Ho questo esempio di base TextSwitcher che utilizza un TextView vuoto di lavoro ok:Caricamento di TextView da xml in un TextSwitcher

.java 

public class TextSwitcherTest extends Activity 
{ 
    private TextSwitcher textSwitcher; 

    private ViewFactory viewFactory = new ViewFactory() 
    { 
     public View makeView() 
     { 
      TextView textView = new TextView(TextSwitcherTest.this); 

      return textView; 
     } 
    }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.main); 

     textSwitcher = (TextSwitcher) findViewById(R.id.textSwitcher); 

     textSwitcher.setFactory(viewFactory); 

     Animation in = AnimationUtils.loadAnimation(this,android.R.anim.fade_in); 
     Animation out = AnimationUtils.loadAnimation(this,android.R.anim.fade_out); 

     textSwitcher.setInAnimation(in); 
     textSwitcher.setOutAnimation(out); 

     textSwitcher.setText("test ok"); 
    }  
} 

-

main.xml 

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <TextSwitcher 
     android:id="@+id/textSwitcher" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" /> 

</LinearLayout> 

Ma quando cambio il codice per cercare di caricare un TextView da un file XML, sputa un mucchio di errori. Ecco il codice modificato:

.java 

public class TextSwitcherTest extends Activity 
{ 
    private TextSwitcher textSwitcher; 

    private ViewFactory viewFactory = new ViewFactory() 
    { 
     public View makeView() 
     { 
      LayoutInflater inflater = LayoutInflater.from(TextSwitcherTest.this); 

      TextView textView = (TextView) inflater.inflate(R.id.textView,null); 

      return textView; 
     } 
    }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.main); 

     textSwitcher = (TextSwitcher) findViewById(R.id.textSwitcher); 

     textSwitcher.setFactory(viewFactory); 

     Animation in = AnimationUtils.loadAnimation(this,android.R.anim.fade_in); 
     Animation out = AnimationUtils.loadAnimation(this,android.R.anim.fade_out); 

     textSwitcher.setInAnimation(in); 
     textSwitcher.setOutAnimation(out); 

     textSwitcher.setText("test ok"); 
    }  
} 

-

textview.xml 

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="@string/hello" /> 

</LinearLayout> 

Chiunque può offrire un suggerimento dove sto andando male? Il codice viene compilato correttamente, ma sono sicuro che con il LayoutInflater venga utilizzato in qualche modo in modo errato?


messaggi di errore (che non presenta più '11 '):

07-22 03:51:24.096: W/dalvikvm(580): threadid=1: thread exiting with uncaught exception (group=0x409c01f8) 
07-22 03:51:24.137: E/AndroidRuntime(580): FATAL EXCEPTION: main 
07-22 03:51:24.137: E/AndroidRuntime(580): java.lang.RuntimeException: Unable to start activity ComponentInfo{test09.TextSwitcher01/test09.TextSwitcher01.TextSwitcherTest}: android.content.res.Resources$NotFoundException: Resource ID #0x7f050001 type #0x12 is not valid 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.app.ActivityThread.access$600(ActivityThread.java:123) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.os.Handler.dispatchMessage(Handler.java:99) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.os.Looper.loop(Looper.java:137) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.app.ActivityThread.main(ActivityThread.java:4424) 
07-22 03:51:24.137: E/AndroidRuntime(580): at java.lang.reflect.Method.invokeNative(Native Method) 
07-22 03:51:24.137: E/AndroidRuntime(580): at java.lang.reflect.Method.invoke(Method.java:511) 
07-22 03:51:24.137: E/AndroidRuntime(580): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
07-22 03:51:24.137: E/AndroidRuntime(580): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
07-22 03:51:24.137: E/AndroidRuntime(580): at dalvik.system.NativeStart.main(Native Method) 
07-22 03:51:24.137: E/AndroidRuntime(580): Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f050001 type #0x12 is not valid 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.content.res.Resources.loadXmlResourceParser(Resources.java:2110) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.content.res.Resources.getLayout(Resources.java:857) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.view.LayoutInflater.inflate(LayoutInflater.java:394) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.view.LayoutInflater.inflate(LayoutInflater.java:352) 
07-22 03:51:24.137: E/AndroidRuntime(580): at test09.TextSwitcher01.TextSwitcherTest$1.makeView(TextSwitcherTest.java:23) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.widget.ViewSwitcher.obtainView(ViewSwitcher.java:80) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.widget.ViewSwitcher.setFactory(ViewSwitcher.java:99) 
07-22 03:51:24.137: E/AndroidRuntime(580): at test09.TextSwitcher01.TextSwitcherTest.onCreate(TextSwitcherTest.java:38) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.app.Activity.performCreate(Activity.java:4465) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049) 
07-22 03:51:24.137: E/AndroidRuntime(580): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920) 
07-22 03:51:24.137: E/AndroidRuntime(580): ... 11 more 
+0

per favore aggiungi la "pila di errori" – Shine

+0

ok allora, scusa non li ho inclusi prima! – Spoonface

risposta

14

Ci sono diverse cose sbagliate con il tuo codice:

In primo luogo, il metodo LayoutInflater.inflate() aspetta l'id di un file di layout in forma di R.layout.layout_name e non in forma di R.id.some_id:

TextView textView = (TextView) inflater.inflate(R.layout.textView, null); 

In secondo luogo, il codice che utilizzi genererà un valore ClassCastException perché la radice del layout gonfiato è un LinearLayout e non un TextView mentre provi a lanciarlo. Il tuo codice dovrebbe essere:

LinearLayout ll = (Linearlayout) inflater.inflate (R.layout.textView, null);

Ma anche la linea di cui sopra non funziona perché, come suggerisce il nome, un TextSwitcher vorranno solo figli di tipo TextView, nulla può frapporsi tra l'TextSwitcher ei due figli TextView. Il codice corretto da utilizzare sarà alla fine:

Layout per textview.xml:

<?xml version="1.0" encoding="utf-8"?> 
<TextView 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/textView" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello" /> 

E il campo viewFactory sarà:

private ViewFactory viewFactory = new ViewFactory() { 
     public View makeView() { 
      LayoutInflater inflater = LayoutInflater.from(TextSwitcherTest.this); 
      TextView textView = (TextView) inflater.inflate(R.layout.textView, null); 
      return textView; 
     } 
}; 
+0

Ciao, capisco ora. Grazie per il tuo tempo molto apprezzato! – Spoonface

+0

dovrebbe il rootview essere nullo? –

+1

@DennisAnderson rootView deve essere nullo solo quando non si desidera allegare la vista gonfiata a rootView (in pratica quando si desidera semplicemente gonfiare un layout senza collegarlo (al momento dell'inflazione) a un'altra vista). Dai un'occhiata alla documentazione del metodo inflate() che accetta anche un parametro booleano 'https://developer.android.com/reference/android/view/LayoutInflater.html#inflate(org.xmlpull.v1.XmlPullParser, android .view.ViewGroup, boolean) ' – Luksprog

0

sono arrivato fino a questa soluzione , che per me è il più vicino alla definizione di TextView direttamente nell'XML:

Innanzitutto, definire TextSwitcher con due TextView o bjects al suo interno, con la definizione personalizzata:

 <TextSwitcher 
      android:fontFamily="sans-serif-condensed" 
      android:id="@+id/detail_date_textswitch" 
      android:layout_height="wrap_content" 
      android:layout_width="match_parent"> 
      <TextView 
       android:id="@+id/detail_date_textview1" 
       android:textColor="@color/grey_700" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:textSize="20sp"/> 
      <TextView 
       android:id="@+id/detail_date_textview2" 
       android:textColor="@color/grey_700" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:textSize="20sp"/> 
     </TextSwitcher> 

Dopo di che, nel codice, definire quanto segue fabbrica per l'oggetto TextSwitcher:

textSwitcher.setFactory(new ViewSwitcher.ViewFactory() { 
     boolean isFirst = true; 
     @Override 
     public View makeView() { 
      if (isFirst) { 
       isFirst = false; 
       TextView textView = (TextView) mDateView.findViewById(R.id.detail_date_textview1); 
       mDateView.removeViewAt(0); 
       return textView; 
      } else { 
       TextView textView = (TextView) mDateView.findViewById(R.id.detail_date_textview2); 
       mDateView.removeViewAt(0); 
       return textView; 
      } 
     } 
    }); 

non voglio dire che non è un po 'difficile, Ma ha funzionato per me.

1

In realtà, non è necessario impostare fabbrica se si inseriscono due TextViews all'interno del proprio file TextSwitcher in XML. Questo ha funzionato per me:

<TextSwitcher 
    android:id="@+id/id1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:inAnimation="@android:anim/fade_in" 
    android:outAnimation="@android:anim/fade_out"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:lines="1"/> 
    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:lines="1"/> 
</TextSwitcher> 

(alcuna configurazione aggiuntiva fatto in codice, basta inflate e findViewById)

Tuttavia, è necessario duplicare gli attributi di tutto il TextViews. Questo potrebbe essere evitato spostando il TextView al file separato e quindi tra cui due volte:

<TextSwitcher 
    android:id="@+id/id1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:inAnimation="@android:anim/fade_in" 
    android:outAnimation="@android:anim/fade_out"> 

    <include layout="@layout/titlebar" /> 
    <include layout="@layout/titlebar" /> 
</TextSwitcher> 

Altro modo per evitare la duplicazione sarebbe la creazione di uno stile personalizzato e la sua applicazione ad entrambi TextViews.

+0

Ben fatto! Questo è il modo più pulito. – Josselin

Problemi correlati