カスタムアダプターでlayoutinflaterを使用できません
-
29-09-2019 - |
質問
ListViewを1行あたり3つのTextViewに入力するカスタムアダプターの作成を検討しています。これを行うためにかなりの例のコードを見つけましたが、最高のと思われるものは次のとおりでした。 http://www.anddev.org/custom_widget_adapters-t1796.html
最新のAndroid SDKでいくつかのコンパイラの問題を修正するためのいくつかのマイナーな調整の後、私はそれを実行しました、例外を取得するためだけに:
エラー/androidruntime(281):java.lang.unsupportedoperationexception:addview(view、layoutparams)はadapterviewでサポートされていません
だから私は多くの研究をし、これのための多くの考えられる理由と修正を見つけました。どれも物事を変えませんでした。私のアダプターコードは現在です:
public class WeatherAdapter extends BaseAdapter {
private Context context;
private List<Weather> weatherList;
public WeatherAdapter(Context context, int rowResID,
List<Weather> weatherList ) {
this.context = context;
this.weatherList = weatherList;
}
public int getCount() {
return weatherList.size();
}
public Object getItem(int position) {
return weatherList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
Weather weather = weatherList.get(position);
//LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.weather_row, null, true);
TextView cityControl = (TextView)v.findViewById( R.id.city );
TextView temperatureControl = (TextView)v.findViewById( R.id.temperature );
ImageView skyControl = (ImageView)v.findViewById( R.id.sky );
return v;
}
}
それで、私はインフレーターを取得する方法と、現在は除外されていないコメントを試しました。私は「親」を膨らませ、nullを膨らませ、「真の」、「false」を渡し、最後のパラメーターを完全に省略しようとしました。それらのどれも機能しておらず、私がこれまでに発見したすべての例は2008年から、少し時代遅れだと感じています。
誰かがこれを手伝ってくれるなら、私は問題を解決したいと思います。
解決
私も初心者ですので、この答えを一杯の塩で受け止めてください - それが機能しない場合は、先に進み、もう少しグーグルしてください。よく知らない AdapterView
私は伝統的に持っているので ListView
また GridView
カスタムアダプターが延長されました BaseAdapter
その後 listView.setAdapter(myCustomAdapter)
.
内部でこのようなものを作ってみることができます WeatherAdapter
クラス:
public void addToList(Weather mWeather) {
weatherList.add(mWeather);
}
次に、呼び出すクラスで WeatherAdapter
:
weatherAdapter.addToList(weatherToAdd);
weatherAdapter.notifyDataSetChanged();
また、GetViewメソッドでさらに最適化する必要があります。
他のヒント
このラインは過失だと思います:
View v = inflater.inflate(R.layout.weather_row, null, true);
代わりに必要です:
View v = inflater.inflate(R.layout.weather_row, parent, false);
falseは、親から独立している膨らんだビューを、それに添付されていません。 AdapterView
s。なぜそうなのか、私は完全に困惑させますが、上記のパターンは私のために働きました。
のために AdaptertView addView
方法:
void addview(子を見る)
この方法はサポートされておらず、呼び出されたときにunsupportedoperationExceptionをスローします。」(Androidドキュメントから)
おそらく膨張手順が呼び出します addView
方法とこれはanから不可能です AdapterView
, 、またはその AdapterView
.
ドキュメントから:
「アダプターオブジェクトは、アダプタービューとそのビューの基礎となるデータの間のブリッジとして機能します。アダプターはデータ項目へのアクセスを提供します。アダプターは、データセットの各アイテムのビューを作成する責任もあります」。
膨張操作は、あなたの見解や他のすべての操作をモデル化する単純なアクティビティ、たとえば他のクラスでデータを取得し、データを表示する簡単なアクティビティから実行できると思います。
それが役立つことを願っています!
@axel22の答えが重要ですが、コードには他にもいくつかのものがありません。まず、好みに応じて、BaseadapterまたはArrayAdapterを拡張する必要があります。第二に、ビューホルダーを使用して、FindViewByIDへの過度の呼び出しを避け、(最も重要なことに)あなたのビューをリサイクルすることを避ける練習をしたいと思います。
private Class ViewHolder {
public TextView cityControl;
public TextView temperatureControl;
public ImageView skyControl;
public ViewHolder(TextView cityControl, TextView temperatureControl, ImageView skyControl) {
this.cityControl = cityControl;
this.temperatureControl = temperatureControl;
this.skyControl = skyControl;
}
GetView関数はビューをリサイクルして利用できます ViewHolder
次のようなクラス:
public View getView(int position, View convertView, ViewGroup parent) {
Weather weather = weatherList.get(position);
// This is how you attempt to recycle the convertView, so you aren't
// needlessly inflating layouts.
View v = convertView;
ViewHolder holder;
if (null == v) {
v = LayoutInflater.from(getContext()).inflate(R.layout.weather_row, parent, false);
TextView cityControl = (TextView)v.findViewById( R.id.city );
TextView temperatureControl = (TextView)v.findViewById( R.id.temperature );
ImageView skyControl = (ImageView)v.findViewById( R.id.sky );
holder = new ViewHolder(cityControl, temperatureControl, skyControl);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.cityControl.setText("Metropolis");
holder.temperatureControl.setText("78");
holder.skyControl.setImageResource(R.drawable.daily_planet);
return v;
}
さらに、より多くの例(およびその他の最適化のヒント)については、 このブログ投稿 (またはビューホルダーのためのGoogle)。