Android SherlockListFragment列表适配器,每个项目都有自定义布局

时间:2013-07-19 19:13:11

标签: android android-layout android-listfragment

如果在获取的JSONObject上可用,我有一个SherlockListFragment来显示包含某些信息的列表。有四种类型的信息:电话,网站,位置和营业时间,每个信息都有自己的“图标”显示在列表中。所以,我的问题是如何显示每种类型的自定义布局,以及如何以编程方式从列表中添加和删除项目。 提前致谢

2 个答案:

答案 0 :(得分: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);
      }


}

我个人认为第二种方法很脏。 :)

我希望这会给你一些想法。 :)

答案 1 :(得分:0)

最好的办法是在ListAdapter的getView(int,View,ViewGroup)方法中处理它。如果使用上下文和JSONObjects(在数组或JSONArray中)构造适配器,则使用每个JSONObjects的has(String)方法检查它是什么非常简单。根据对象的不同,只需膨胀不同的布局。

适配器中的getView(int,View,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;
}

您可能希望在每个if语句中执行更多操作,例如添加单击侦听器或其他...除非您的视图上有自动链接。如果您依靠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>