[解決済み] Recyclerviewと異なるタイプの行のインフレーションの処理
質問
私は、新しい
RecyclerView
の例を見つけられませんでした。
RecyclerView
で、異なるタイプの行/カードビューが膨張している例は見つかりませんでした。
とは
ListView
をオーバーライドして
getViewTypeCount
と
getItemViewType
で、異なるタイプの行を処理するためのものです。
私はそれを"old"のように行うことになっていますか、私は何かで行う必要があります
LayoutManager
? どなたか正しい方向を教えていただけませんか?なぜなら、私は1つのタイプの例しか見つけることができないからです。
私は少し異なるカードのリストを持ちたいのです。または、私はちょうど
scrollView
と
cardViews
の中にある...アダプターなしで作って
recyclerView
?
どのように解決するのですか?
iOSのUITableViewのような行/項ロジックをAndroidで扱うのは、iOSほど簡単ではありませんが、RecyclerViewを使うと、できることの柔軟性ははるかに高くなります。
結局のところ、Adapterでどのようなビューを表示しているのかを把握することが重要です。
結局のところ、Adapter でどのようなビューを表示しているのかを把握する方法がすべてです。
アダプタはふたつのメソッドを公開しており、これらはオーバーライドする必要があります。
getItemViewType(int position)
このメソッドのデフォルトの実装は常に0を返し、ビューの種類が1つしかないことを示します。あなたのケースでは、そうではありません。したがって、どの行がどのビュータイプに対応するかを表明する方法を見つける必要があります。行とセクションでこれを管理する iOS とは異なり、ここでは依存するインデックスは 1 つだけで、位置がセクションヘッダーに関連するときと、通常の行に関連するときを知るために、開発者のスキルを使用する必要があります。
createViewHolder(ViewGroup parent, int viewType)
いずれにせよこのメソッドをオーバーライドする必要がありますが、通常、人々は viewType パラメータを無視するだけです。ビュータイプに応じて、正しいレイアウトリソースをインフレートし、それに応じてビューホルダーを作成する必要があります。RecyclerViewは、異なるビュータイプの衝突を回避する方法で、異なるビュータイプのリサイクルを処理します。
のようなデフォルトのLayoutManagerを使おうと思っているならば、そのようなリソースは必要ありません。
LinearLayoutManager
のようなデフォルトの LayoutManager を使うつもりなら、問題ないでしょう。もし、あなた自身の LayoutManager の実装を作ろうと思っているなら、もう少し頑張る必要があるでしょう。あなたが実際に扱わなければならない唯一の API は
findViewByPosition(int position)
で、これは特定の位置で与えられたビューを提供します。おそらく、あなたはどのような
タイプ
に応じて異なるレイアウトをしたいと思うでしょうから、いくつかのオプションがあります。
-
通常、ViewHolderパターンを使用する場合、ビューホルダーでビューのタグを設定します。これを表現するフィールドをビューホルダーに追加することで、レイアウトマネージャーの実行時にこれを使用して、ビューがどのようなタイプであるかを見つけることができます。
-
どの位置がどのビュータイプに相関するかを決定する関数が必要になるので、このメソッドを何らかの方法でグローバルにアクセスできるようにするとよいでしょう(データを管理するシングルトンクラスとか?)、そして、位置に従って同じメソッドを単にクエリーすることができます。
以下はコードサンプルです。
// in this sample, I use an object array to simulate the data of the list.
// I assume that if the object is a String, it means I should display a header with a basic title.
// If not, I assume it's a custom model object I created which I will use to bind my normal rows.
private Object[] myData;
public static final int ITEM_TYPE_NORMAL = 0;
public static final int ITEM_TYPE_HEADER = 1;
public class MyAdapter extends Adapter<ViewHolder> {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == ITEM_TYPE_NORMAL) {
View normalView = LayoutInflater.from(getContext()).inflate(R.layout.my_normal_row, null);
return new MyNormalViewHolder(normalView); // view holder for normal items
} else if (viewType == ITEM_TYPE_HEADER) {
View headerRow = LayoutInflater.from(getContext()).inflate(R.layout.my_header_row, null);
return new MyHeaderViewHolder(headerRow); // view holder for header items
}
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final int itemType = getItemViewType(position);
if (itemType == ITEM_TYPE_NORMAL) {
((MyNormalViewHolder)holder).bindData((MyModel)myData[position]);
} else if (itemType == ITEM_TYPE_HEADER) {
((MyHeaderViewHolder)holder).setHeaderText((String)myData[position]);
}
}
@Override
public int getItemViewType(int position) {
if (myData[position] instanceof String) {
return ITEM_TYPE_HEADER;
} else {
return ITEM_TYPE_NORMAL;
}
}
@Override
public int getItemCount() {
return myData.length;
}
}
これらのビューホルダーがどのように見えるかのサンプルは以下のとおりです。
public MyHeaderViewHolder extends ViewHolder {
private TextView headerLabel;
public MyHeaderViewHolder(View view) {
super(view);
headerLabel = (TextView)view.findViewById(R.id.headerLabel);
}
public void setHeaderText(String text) {
headerLabel.setText(text);
}
}
public MyNormalViewHolder extends ViewHolder {
private TextView titleLabel;
private TextView descriptionLabel;
public MyNormalViewHolder(View view) {
super(view);
titleLabel = (TextView)view.findViewById(R.id.titleLabel);
descriptionLabel = (TextView)view.findViewById(R.id.descriptionLabel);
}
public void bindData(MyModel model) {
titleLabel.setText(model.getTitle());
descriptionLabel.setText(model.getDescription());
}
}
もちろん、このサンプルはデータソース (myData) がこのように簡単にアダプタを実装できるように構築されていることを前提にしています。例として、名前のリストを表示し、名前の一文字目が変わるたびにヘッダを表示する (リストはアルファベット順とする) データソースを構築する方法を紹介します。
// Assume names & descriptions are non-null and have the same length.
// Assume names are alphabetized
private void processDataSource(String[] names, String[] descriptions) {
String nextFirstLetter = "";
String currentFirstLetter;
List<Object> data = new ArrayList<Object>();
for (int i = 0; i < names.length; i++) {
currentFirstLetter = names[i].substring(0, 1); // get the 1st letter of the name
// if the first letter of this name is different from the last one, add a header row
if (!currentFirstLetter.equals(nextFirstLetter)) {
nextFirstLetter = currentFirstLetter;
data.add(nextFirstLetter);
}
data.add(new MyModel(names[i], descriptions[i]));
}
myData = data.toArray();
}
この例はかなり特殊な問題を解決するためのものですが、リサイクラーでさまざまな種類の行を処理する方法の概要を理解し、自分のコードに必要な修正を加えて、自分のニーズに合うようにできるようになるとよいでしょう。
関連
-
[解決済み] SDカードからファイルを削除する方法を教えてください。
-
[解決済み] Android Debug Bridgeでアプリケーションのインストール時にINSTALL_FAILED_VERSION_DOWNGRADEを無視する方法はありますか?
-
[解決済み] Eclipseでのandroid:configChangesでのAdmobエラー
-
[解決済み] handler.postDelayed()を停止する。
-
[解決済み] 「KotlinとAndroidで「パラメータTを推測するのに十分な情報がありません。
-
[解決済み] AppCompat-v7 21でアクションバー/ツールバーにアイコンを表示する。
-
[解決済み] Androidアプリケーションのヒープサイズを大きくするには?
-
[解決済み] 非推奨のandroid.support.v4.app.ActionBarDrawerToggleの置き換え方法
-
[解決済み] Androidでツールバーの戻るボタンの色を変えるには?
-
[解決済み] クリアリング・インテント
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] android: imageview の画像を画面に合わせて伸縮させる
-
[解決済み] BottomSheetDialogFragmentの状態をexpandedに設定する。
-
[解決済み] wrap_contentでRelativeLayoutがフルスクリーンになってしまう
-
[解決済み] FloatingActionButtonのサンプルとサポートライブラリ
-
[解決済み] Android Studioの「未実装メソッドの追加」機能
-
[解決済み] 文字サイズとアンドロイドの画面サイズの違い
-
[解決済み] ArrayList<MyCustomClass>をJSONArrayに変換する。
-
[解決済み] フラグメント間の値の受け渡し方法
-
[解決済み] Gradleでビルドタイプを使用し、ContentProviderを使用する同じアプリを1つのデバイスで実行する。
-
[解決済み] BottomNavigationViewを新しいNavControllerで使用する際に、フラグメントを生かす方法はありますか?