如果在获取的 JSONObject 上可用,我有一个 SherlockListFragment 来显示包含某些信息的列表。有四种类型的信息:电话、网站、位置和开放时间,每一种都有自己的“图标”显示在列表中。所以,我的问题是如何为每种类型显示自定义布局,以及如何以编程方式从列表中添加和删除项目。提前致谢
2 回答
创建接口(或抽象类),让我们说:
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
}
}
ETC...
使您的适配器采用 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);
}
}
我个人认为第二种方法很脏。:)
我希望这能给你一些想法。:)
最好的办法是在 ListAdapter 的 getView(int, View, ViewGroup) 方法中处理它。如果您使用上下文和 JSONObjects(在数组或 JSONArray 中)构建适配器,则使用每个 JSONObjects 的 has(String) 方法来检查它是非常简单的。只需根据对象具有的不同布局膨胀。
Adapter 中的 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 来解决数据的可点击性,那么您不需要膨胀不同的布局,您可以只使用 switch 图标。
@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>