2012-10-08 56 views
11

正如我看到的以前提出的問題,自定義適配器類裏面(比如,MyAdapter擴展ArrayAdapter)他們總是用充氣XML列表項佈局。我所希望做的就是創建完全使用Java和XML沒有一切...創建通過編程自定義列表項Android的一個ListView - 沒有XML列表項目佈局

// for example 
String[] wordlist = new String[] {a, b, c}; 

LinearLayout list_item_layout = new LinearLayout(this); 
list_item_layout.setId(5000); 

TextView listText = new TextView(this); 
listText.setId(5001); 

listLayout.addView(listText); 

ListView list = new ListView(this); 

// ** QUESTION ** do I declare a programmatic .setAdapter() like this? 
// ** TAKE NOTE ** I passed 'wordlist' here.. 
list.setAdapter(new MyAdapter(this, list_item_layout.getId(), listText.getId(), wordlist)); 

,然後MyAdapter ...

private class MyAdapter extends ArrayAdapter<String> { 

    public MyAdapter(Context context, int resource, int textViewResourceId, String[] strings) { 
     super(context, resource, textViewResourceId, strings); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     View v = convertView; //is this the list_item_layout that I passed?? 
     TextView tv = (TextView) v.findViewById(5001); 

     // ** QUESTION ** do I pass 'wordlist' again here? 
     tv.setText(wordlist[position]); 

     return v; 
    } 
} 

當我在我的設備上運行此發生的是我得到以下錯誤...

10-08 23:11:19.775: E/AndroidRuntime(18276): FATAL EXCEPTION: main 
    10-08 23:11:19.775: E/AndroidRuntime(18276): android.content.res.Resources$NotFoundException: String resource ID #0x0 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at android.content.res.Resources.getText(Resources.java:222) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at android.widget.TextView.setText(TextView.java:3011) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at com.turista.client.TuristaClientMain.onClick(TuristaClientMain.java:113) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at android.view.View.performClick(View.java:2538) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at android.view.View$PerformClick.run(View.java:9152) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at android.os.Handler.handleCallback(Handler.java:587) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at android.os.Handler.dispatchMessage(Handler.java:92) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at android.os.Looper.loop(Looper.java:123) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at android.app.ActivityThread.main(ActivityThread.java:3691) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at java.lang.reflect.Method.invokeNative(Native Method) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at java.lang.reflect.Method.invoke(Method.java:507) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605) 
    10-08 23:11:19.775: E/AndroidRuntime(18276): at dalvik.system.NativeStart.main(Native Method) 

任何人都可以解釋如何以編程方式做到這一點?


* EDITED * 2012年10月9日


好吧,因爲我仍然停留在這個問題上,我認爲我做了一些改進,但仍然得到錯誤信息。改進後的代碼如下..

//wordlist is a global variable 
String[] wordlist = new String[] {a, b, c}; 

// .. 
// .. inside onCreate... 

ListView list = new ListView(this); 
     list.setAdapter(new MyAdapter(this, R.layout.listitem, R.id.mLargeTextView, wordlist)); 
// since the ArrayAdapter class needs XML parameters to inflate, I created a dummy layout 
現在MyAdapter類中

..

private class MyAdapter extends ArrayAdapter<String> { 

    public MyAdapter(Context context, int resource, int textViewResourceId, String[] strings) { 
     super(context, resource, textViewResourceId, strings); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 


     LinearLayout listLayout = new LinearLayout(Main.this); 
     listLayout.setLayoutParams(new LayoutParams(wrapContent, wrapContent)); 
     listLayout.setId(5000); 

     TextView listText = new TextView(Main.this); 
     listText.setId(5001); 

     listLayout.addView(listText); 

     listText.setText(wordlist[position]); 

     return listLayout; 
    } 
} 

正如你所看到的,我想我要重寫getView爲了顯示我的自定義視圖,所以這是我做了什麼。不幸的是我想我誤解了它。下面是錯誤..

10-09 09:24:10.095: E/AndroidRuntime(2517): FATAL EXCEPTION: main 
    10-09 09:24:10.095: E/AndroidRuntime(2517): java.lang.ClassCastException: android.view.ViewGroup$LayoutParams 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.ListView.measureScrapChild(ListView.java:1183) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.ListView.measureHeightOfChildren(ListView.java:1266) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.ListView.onMeasure(ListView.java:1175) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.View.measure(View.java:8366) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.View.measure(View.java:8366) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.View.measure(View.java:8366) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.LinearLayout.measureVertical(LinearLayout.java:386) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.LinearLayout.onMeasure(LinearLayout.java:309) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at com.android.internal.widget.WeightedLinearLayout.onMeasure(WeightedLinearLayout.java:60) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.View.measure(View.java:8366) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.View.measure(View.java:8366) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.widget.FrameLayout.onMeasure(FrameLayout.java:250) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.View.measure(View.java:8366) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.ViewRoot.performTraversals(ViewRoot.java:847) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1868) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.os.Handler.dispatchMessage(Handler.java:99) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.os.Looper.loop(Looper.java:123) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at android.app.ActivityThread.main(ActivityThread.java:3691) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at java.lang.reflect.Method.invokeNative(Native Method) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at java.lang.reflect.Method.invoke(Method.java:507) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605) 
    10-09 09:24:10.095: E/AndroidRuntime(2517):  at dalvik.system.NativeStart.main(Native Method) 
+0

我可以問你爲什麼想這樣做編程風格,而不是使用XML? – Zerkz

+0

你已經設置了id爲什麼你正在用這個id找到新的TextView?使用tv.getID()。 –

+0

@Kumar你是什麼意思?我用v.findViewById(5001)。 – daryl

回答

21

ListView延伸AbsListView這又延伸AdapterView延伸視圖組。所以ListView所有的孩子將被添加到ViewGroup。因此,要設置佈局參數,可以 使用ViewGroup.LayoutParam,同時設置佈局參數有關listLayout

或者嘗試AbsListView.LayoutParams設置佈局參數有關listLayout

請嘗試,讓我知道,如果它的工作。

下面的代碼是工作的罰款..

public class MainActivity1 extends Activity { 

    String[] wordlist = new String[] { "a", "b", "c" }; 

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

     ListView list = new ListView(this); 
     list.setAdapter(new MyAdapter(this, wordlist)); 

     setContentView(list); 
    } 

    private class MyAdapter extends ArrayAdapter<String> { 

     public MyAdapter(Context context, String[] strings) { 
      super(context, -1, -1, strings); 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 

      LinearLayout listLayout = new LinearLayout(MainActivity1.this); 
      listLayout.setLayoutParams(new AbsListView.LayoutParams(
        AbsListView.LayoutParams.WRAP_CONTENT, 
        AbsListView.LayoutParams.WRAP_CONTENT)); 
      listLayout.setId(5000); 

      TextView listText = new TextView(MainActivity1.this); 
      listText.setId(5001); 

      listLayout.addView(listText); 

     listText.setText(super.getItem(position)); 

      return listLayout; 
     } 
    } 
} 

的問題是,默認的Eclipse進口ViewGroup.LayoutParams這是與需要被用於設置佈局參數有關視圖從getView()方法返回的AbsListView.LayoutParams不兼容。

請檢查並讓我知道如何去..

+0

剛剛用AbsListView.LayoutParams進行測試,它工作正常。相應地更新了我的答案.. –

+0

哇,它的工作原理。我不知道在這個getView()方法中,LayoutParams的處理方式不同,並且嚴重依賴Eclipse提供的自動導入功能並不是一件好事。 – daryl

+0

謝謝。我幾乎放棄了這個想法,以編程方式做所有事情。 最後一個問題,我可以看到你在onCreate中的setAdapter(new MyAdapter())內傳遞了數組'wordlist'。那意味着它必須已經在MyAdapter裏面了......如果'wordlist'沒有全局聲明,你怎麼稱呼它? 再次感謝你Praful。你完全釘了它。 – daryl

2

要添加到上面的回答,設定ID都具有恆定的數字是不是一個好主意。

更換,listLayout.setId(5000);用,listLayout.setId(View.generateViewId());

如果你的目標API 16及以下,參照this.

相關問題