——这个不难,记住很简单
所以对于显示天气,今天和未来天气的item可以同时适配的。
这个是CursorAdapter中的一个函数
/** * @see android.widget.ListAdapter#getView(int, View, ViewGroup) */
public View getView(int position, View convertView, ViewGroup parent) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
View v;
if (convertView == null) {
v = newView(mContext, mCursor, parent);
} else {
v = convertView;
}
bindView(v, mContext, mCursor);
return v;
}
看到其中的newView和bindView就是继承CursorAdapter的类需要自己实现的。
回到主题上,在MULTIPLE中,today和future_day是两种view。这就需要override CursorAdapter中两个关于view type的函数:
public int getItemViewType(int position);
public int getViewTypeCount();
第一个是根据cursor中记录的位置返回view type,(返回值从0,1,2,……)在天气中就是,位置在0的记录为今天的天气,需要返回VIEW_TYPE_TODAY;其他位置则为未来天气的记录,返回VIEW_TYPE_FUTURE_DAY。
第二个是返回view type的数目,还是说天气这个,显然是两种,则返回2;view type的范围自然就是0和1了。
下面是Forecast部分:(忽略bindView部分,填充View的部分)
public class ForecastAdapter extends CursorAdapter{
private final int VIEW_TYPE_TODAY = 0;
private final int VIEW_TYPE_FUTURE_DAY = 1;
private final int VIEW_TYPE_COUNT = 2;
public ForecastAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}
@Override
public int getItemViewType(int position){
return (position == 0) ? VIEW_TYPE_TODAY : VIEW_TYPE_FUTURE_DAY;
}
@Override
public int getViewTypeCount(){
return VIEW_TYPE_COUNT;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
//View view = LayoutInflater.from(context).inflate(R.layout.list_item_forecast,parent,false);
//Choose the layout type
int viewType = getItemViewType(cursor.getPosition());
int layoutId = -1;
//TODO: Determine layoutId from viewType
switch (viewType){
case VIEW_TYPE_TODAY:
layoutId = R.layout.list_item_forecast_today;
break;
case VIEW_TYPE_FUTURE_DAY:
layoutId = R.layout.list_item_forecast;
break;
}
return LayoutInflater.from(context).inflate(layoutId,parent , false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
//Read weather icon ID from cursor
//Use placeholder image for now
//TODO Read date from cursor
//TODO Read weather forecast from cursor
//Read user preference for metric or imperial temperature units
//Read high temperature from cursor
//TODO Read low temperature from cursor
}
}
这是bindView中的内容,读取出记录,然后填充相应的view,显示。
/* This is where we fill-in the views with the contents of the cursor. */
@Override
public void bindView(View view, Context context, Cursor cursor) {
// our view is pretty simple here --- just a text view
// we'll keep the UI functional with a simple (and slow!) binding.
// Read weather icon ID from cursor
int weatherId = cursor.getInt(ForecastFragment.COL_WEATHER_ID);
// Use placeholder image for now
ImageView iconView = (ImageView) view.findViewById(R.id.list_item_icon);
iconView.setImageResource(R.drawable.ic_launcher);
// Read date from cursor
long dateInMillis = cursor.getLong(ForecastFragment.COL_WEATHER_DATE);
// Find TextView and set formatted date on it
TextView dateView = (TextView) view.findViewById(R.id.list_item_date_textview);
dateView.setText(Utility.getFriendlyDayString(context, dateInMillis));
// Read weather forecast from cursor
String description = cursor.getString(ForecastFragment.COL_WEATHER_DESC);
// Find TextView and set weather forecast on it
TextView descriptionView = (TextView) view.findViewById(R.id.list_item_forecast_textview);
descriptionView.setText(description);
// Read user preference for metric or imperial temperature units
boolean isMetric = Utility.isMetric(context);
// Read high temperature from cursor
double high = cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP);
TextView highView = (TextView) view.findViewById(R.id.list_item_high_textview);
highView.setText(Utility.formatTemperature(high, isMetric));
// Read low temperature from cursor
double low = cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP);
TextView lowView = (TextView) view.findViewById(R.id.list_item_low_textview);
lowView.setText(Utility.formatTemperature(low, isMetric));
}
这里面的图片、日期、高温、低温、预报等item看起来很杂乱,我们可以使用ViewHolder让它看起来清爽一些:
在ForecastAdapter中加入static class ViewHolder
public static class ViewHolder{
private final ImageView iconView;
private final TextView dateView;
private final TextView forecastView;
private final TextView highView;
private final TextView lowView;
public ViewHolder(View view) {
iconView = (ImageView)view.findViewById(R.id.list_item_icon);
dateView = (TextView)view.findViewById(R.id.list_item_date_textview);
forecastView = (TextView)view.findViewById(R.id.list_item_forecast_textview);
highView = (TextView)view.findViewById(R.id.list_item_high_textview);
lowView = (TextView)view.findViewById(R.id.list_item_low_textview);
}
修改newView:
......
View view = LayoutInflater.from(context).inflate(layoutId,parent , false);
ViewHolder viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
return view;
newView则如下所示:(也是有点杂乱的,不过好一些了)
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder viewHolder = (ViewHolder)view.getTag();
viewHolder.iconView.setImageResource(R.drawable.ic_launcher);
long dateMillis = cursor.getLong(ForecastFragment.COL_WEATHER_DATE);
viewHolder.dateView.setText(Utility.getFriendlyDayString(context,dateMillis));
String description = cursor.getString(ForecastFragment.COL_WEATHER_DESC);
viewHolder.descriptionView.setText(description);
//Read user preference for metric or imperial temperature units
boolean isMetric = Utility.isMetric(context);
//Read high temperature from cursor
double high = cursor.getDouble(ForecastFragment.COL_WEATHER_MAX_TEMP);
viewHolder.highView.setText(Utility.formatTemperature(context,high,isMetric));
double low = cursor.getDouble(ForecastFragment.COL_WEATHER_MIN_TEMP);
viewHolder.lowView.setText(Utility.formatTemperature(context, low , isMetric));
}
String转换为Double:
Double.valueOf(testString);