2013-07-19 31 views
0

我有一個SherlockListFragment顯示一個列表與某些信息,如果是在獲取的JSONObject上可用。有四種類型的信息:電話,網站,位置和開放時間,每個人都有自己的「圖標」顯示在列表中。所以,我的問題是如何顯示每種類型的自定義佈局,以及如何以編程方式從列表中添加和刪除項目。 在此先感謝Android SherlockListFragment列表適配器與每個項目的自定義佈局

回答

0

最好的辦法是在ListAdapter的getView(int,View,ViewGroup)方法中處理它。如果使用上下文和JSONObjects(在數組或JSONArray中)構造適配器,使用每個JSONObjects的has(String)方法來檢查它是什麼,這非常簡單。根據哪個對象具有不同的佈局。

的getView(INT,查看,ViewGroup中)方法的適配器:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    try { 
     jsonObject = json.getJSONObject(position); 

     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     if (jsonObject.has("phone")) { 
      convertView = inflater.inflate(R.layout.list_item_phone, null); 
      TextView details = (TextView) convertView.findViewById(R.id.item_message); 
      details.setText(jsonObject.getString("phone")); 
     } else if (jsonObject.has("website")) { 
      convertView = inflater.inflate(R.layout.list_item_website, null); 
      TextView details = (TextView) convertView.findViewById(R.id.item_message); 
      details.setText(jsonObject.getString("phone")); 
     } else if (jsonObject.has("location")) { 
      convertView = inflater.inflate(R.layout.list_item_location, null); 
      TextView details = (TextView) convertView.findViewById(R.id.item_message); 
      details.setText(jsonObject.getString("phone")); 
     } else if (jsonObject.has("opening_hours")) { 
      convertView = inflater.inflate(R.layout.list_item_opening_hours, null); 
      TextView details = (TextView) convertView.findViewById(R.id.item_message); 
      details.setText(jsonObject.getString("phone")); 
     } 

    } catch (JSONException e) { e.printStackTrace(); } 

    return convertView; 
} 

你可能會想,如果語句來完成更多的在每個像添加點擊監聽器或任何...除非你有自動連結對你的看法。如果您依靠autoLink解決數據的可點擊性問題,那麼您不需要膨脹不同的佈局,只需使用切換圖標即可。

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    try { 
     jsonObject = json.getJSONObject(position); 

     if (convertView == null) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.list_item, null); 
      ((TextView) convertView.findViewById(R.id.item_message)).setAutoLinkMask(Linkify.ALL); //autoLink phone, address, etc. 
     } 

     ImageView icon = (ImageView) convertView.findViewById(R.id.item_type_icon); 
     if (jsonObject.has("phone")) { 
      icon.setImageResource(R.id.phone_icon); 
     } else if (jsonObject.has("website")) { 
      icon.setImageResource(R.id.website_icon); 
     } else if (jsonObject.has("location")) { 
      icon.setImageResource(R.id.location_icon); 
     } else if (jsonObject.has("opening_hours")) { 
      icon.setImageResource(R.id.opening_hours_icon); 
     } 

    } catch (JSONException e) { e.printStackTrace(); } 

    return convertView; 
} 

編輯:由於它好像你可能需要單獨視圖動態...

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    try { 
     jsonObject = json.getJSONObject(position); 

     if (convertView == null) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = inflater.inflate(R.layout.list_item, null); //This should have a linear layout with icons and textview for each node... 
     } 

     if (jsonObject.has("phone")) { 
      LinearLayout phoneLayout = (LinearLayout) convertView.findViewById(R.id.phone_layout); //This layout should already have the appropriate icon in it //*/ 
      phoneLayout.setVisibility(View.VISIBLE); //Necessary because the convert view doesn't guarantee what state this will be in as we've been modifiying them. //*/ 
      ((TextView) phoneLayout.findViewById(R.id.message)).setText(jsonObject.getString("phone")); 
     } else { ((LinearLayout) convertView.findViewById(R.id.phone_layout)).setVisibility(View.GONE); } 

     if (jsonObject.has("website")) { 
      LinearLayout websiteLayout = (LinearLayout) convertView.findViewById(R.id.website_layout); 
      websiteLayout.setVisibility(View.VISIBLE); 
      ((TextView) websiteLayout.findViewById(R.id.message)).setText(jsonObject.getString("website")); 
     } else { ((LinearLayout) convertView.findViewById(R.id.website_layout)).setVisibility(View.GONE); } 

     if (jsonObject.has("location")) { 
      LinearLayout locationLayout = (LinearLayout) convertView.findViewById(R.id.location_layout); 
      locationLayout.setVisibility(View.VISIBLE); 
      ((TextView) locationLayout.findViewById(R.id.message)).setText(jsonObject.getString("location")); 
     } else { ((LinearLayout) convertView.findViewById(R.id.location_layout)).setVisibility(View.GONE); } 

     if (jsonObject.has("opening_hours")) { 
      LinearLayout openingHoursLayout = (LinearLayout) convertView.findViewById(R.id.opening_hours_layout); 
      openingHoursLayout.setVisibility(View.VISIBLE); 
      ((TextView) openingHoursLayout.findViewById(R.id.message)).setText(jsonObject.getString("opening_hours")); 
     } else { ((LinearLayout) convertView.findViewById(R.id.opening_hours_layout)).setVisibility(View.GONE); } 

    } catch (JSONException e) { e.printStackTrace(); } 

    return convertView; 
} 

list_item.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:adjustViewBounds="true" 
    android:gravity="center" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="Medium Text" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

    <LinearLayout 
     android:id="@+id/phone_layout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" > 

     <ImageView 
      android:id="@+id/icon" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:src="@drawable/ic_list_item_phone" /> 

     <TextView 
      android:id="@+id/message" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:text="Medium Text" 
      android:textAppearance="?android:attr/textAppearanceMedium" /> 

    </LinearLayout> 

    <LinearLayout 
     android:id="@+id/website_layout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" > 

     <ImageView 
      android:id="@+id/icon" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:src="@drawable/ic_list_item_website" /> 

     <TextView 
      android:id="@+id/message" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:text="Medium Text" 
      android:textAppearance="?android:attr/textAppearanceMedium" /> 

    </LinearLayout> 

    <!-- ETC. A layout for each item. --> 

</LinearLayout> 
+0

很好的答案,謝謝,但如果我想在列表中顯示多個元素呢?我如何進行綁定? –

+0

我明白你現在在做什麼。這就像目錄列表,每個列表可能有多個這些項目。您希望在項目佈局中包含所有選項,並在每個佈局View.GONE不存在時進行設置。我會編輯我的答案。 – Tonithy

+0

是啊!這正是我想要做的:D。那麼這是否會以列表形式誇大我需要的所有佈局? –

1

創建接口(或抽象類),讓說:

public interface DataType{ 

    public MyType getType(); //where MyType is my some enum. 

} 



public enum MyType { TYPE_1(R.layout.layout1), TYPE_2(R.layout.layout2), TYPE_3(R.layout.layout3) 
private resourceId; 
MyType(int resource){ 
resourceId = resource; 
} 
public getResourceLayout(){ 
    return resourceId; 
} 
}; 

在你的類實現這樣的接口:

public class MyData1 implement DataType{ 
    //... 
    @Override 
    public MyType getType(){ 
     return TYPE_1 
    } 

} 

public class MyData2 implement DataType{ 
    //... 
    @Override 
    public MyType getType(){ 
     return TYPE_2 
    } 

} 

等等

製作您的適配器需要DataType類型的對象。

在你的適配器的決定誇大其佈局類似getView()

public View getView(.....){ 
    //..... 
    if(convertView==null){ 
     convetView = mLayoutInflater.inflate(dataAtThatPosition.getResourceLayout(), null); 
     //..... 
    } 
    // use getType() to evaluate further actions if needed based on the type 
} 

另一種方法是離開接口/抽象類的後面,並決定膨脹基於類的分配,其佈局。在這種情況下,您的適配器將採取泛型類型T,決定膨脹哪種佈局,你將不得不做這樣的事情在你的getView()時:

public View getView(.....){ 
     T data = getItemAtPosition(position); 
     if(convertView==null){ 
     convertView = mLayoutInflater.inflate((data.isAssignableFrom(MyData1.class)? R.layout.layout1 : data.isAssignableFrom(MyData2.class)? R.layout.layout1 : R.layout.layout3), null); 
     } 


} 

我個人認爲,第二種方法是非常髒。 :)

我希望這給你的想法。 :)

+0

好一個,我不會想到它,但枚舉MyType具有相同的佈局爲每個元素? –

+0

不,請參閱枚舉的構造函數,有'int'參數,稍後將用於指定不同的佈局並將其放在需要的位置。 對不起,這是我的複製粘貼錯誤,它應該是不同的佈局,我犯了錯誤,通過把所有相同的佈局。:)(已編輯) –

相關問題