2012-07-22 37 views
5

我一直試圖設置一個TextSwitcher加載從XML文件的TextView。我有一個使用一個空的TextView確定工作這一基本TextSwitcher例如:從XML加載TextView到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> 

但是,當我改變代碼,試圖從一個XML文件加載一個TextView,它吐出一堆錯誤。下面是修改後的代碼:

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

任何人都可以給您一個建議,我要去哪裏錯了嗎?代碼編譯好,但我確定這是與LayoutInflater被濫用在某種方式?


錯誤消息(它並沒有顯示更多'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

請添加「堆錯誤」 – Shine 2012-07-22 01:25:15

+0

好吧,對不起,我沒有包括他們更早! – Spoonface 2012-07-22 03:58:27

回答

14

有幾件事情你的代碼錯誤:

首先,LayoutInflater.inflate()方法預計ID佈局文件的格式爲R.layout.layout_name,而不是格式爲R.id.some_id

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

其次,您使用的代碼將拋出ClassCastException,因爲當您試圖對其進行投射時,虛擬佈局的根是LinearLayout而不是TextView。你的代碼應該是:

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

但即使是線以上將無法工作,因爲,正如它的名字暗示,一個TextSwitcher將只需要TextView類型的孩子,沒有什麼能來的TextSwitcher和兩個孩子TextView之間。正確的代碼使用將在年底:

佈局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" /> 

而且viewFactory領域將是:

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

你好,我現在明白了。感謝您的時間非常感謝! – Spoonface 2012-07-22 20:22:42

+0

rootview應爲null? – 2017-10-20 11:59:39

+1

@ DennisAnderson只有當你不想將膨脹的視圖附加到rootView時(基本上當你只想膨脹一個佈局而沒有附加它(在膨脹時)到另一個視圖),rootView應該爲空。查看inflate()方法的文檔,該文檔也採用布爾參數'https://developer.android.com/reference/android/view/LayoutInflater.html#inflate(org.xmlpull.v1.XmlPullParser,android .view.ViewGroup,boolean)' – Luksprog 2017-10-20 15:30:46

0

我想出了這個解決方案,對我來說最接近於直接在XML中定義TextView:

首先,用兩個TextView定義TextSwitcher裏面bjects,與您的自定義的定義:

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

之後,在你的代碼,定義以下廠家爲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; 
      } 
     } 
    }); 

我不會說這不是一種技巧,但它爲我工作。

1

實際上,如果您在佈局XML中的TextSwitcher中放置了兩個TextViews,則不需要設置工廠。這爲我工作:

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

(在代碼中沒有額外的配置完成,只是inflatefindViewById

但是,你必須複製整個TextViews的屬性。這可能通過移動TextView到單獨的文件,然後包括兩次來避免:

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

其他方式來避免重複將創建一個自定義樣式,並把它應用到兩個TextViews

+0

幹得好!這是最乾淨的方式。 – Josselin 2018-01-31 23:58:35