こんにちは、私は同じ問題に直面していて、それを行う方法を見つけました。
私の問題はあなたに似ていました:
「いくつかのロジックを分離したいので、リストビュー内の各アイテムのフラグメントが必要です」
私のアプリでは、垂直 (listView) および水平 (ViewPager) モードでカスタム項目を表示するオプションを提供する必要があります。さらに、18 個のカスタム アイテムをそれぞれ異なるロジックで処理する必要があったため、ListView で ViewPager に使用していたフラグメントを再利用するのが最善の方法でした。
私はそれを手に入れましたが、あなたが試みていた方法ではありません。つまり、「ViewHolders」のようなフラグメントを使用しました:
- 各フラグメントのクラスの変数のようなフラグメントのウィジェットを定義します。
- カスタム ArrayAdapter を作成してオーバーライドします。
getViewTypeCount(), getItemViewType(int position), getCount(), getItem(int position) getView(int position, View convertView, ViewGroup parent)
それぞれの XML を「インgetView
フレート」する前に必要なレイアウトの種類を確認し、フラグメントを作成し、XML からフラグメントにウィジェットを割り当て (を使用rootView.findViewById
)、新しいフラグメントで「タグ」を設定しました。
この時点でわかることは、ListView のフラグメントが Activity にアタッチされていないことですが、必要なものが得られたことです。つまり、いくつかの部分に分散されたロジックと、ListView のすべての利点 (行の再利用、スクロールなど) です。
必要に応じて、コードの一部を投稿できますが、「スパングリッシュ」に対処する必要があります;)。
更新しました
すべての問題は、ViewPager で使用する Fragment を作成するときに、通常、すべての「レイアウト」と「セットアップ」コードがonCreateView
メソッド内にあるためです。
- 使用するビュー オブジェクトを取得します (
View rootView = inflater.inflate(R.layout.fragment_question_horizontal_container, container, false);
)
- 上記のレイアウトからウィジェットを取得し、動作、フォントなどを定義します: (
answer = (EditText)rootView.findViewById(R.id.answer_question_text);
)
この時点まで、奇妙なことは何もありません。
上記の動作でフラグメントを使用する場合は、onCreateView への呼び出しを「エミュレート」し、データを入力して listView に添付する必要があります。
秘訣は次のとおりonCreateView
です。誰が呼び出しているかを気にしないいくつかのメソッドにコードを分割します。私の例onCreateView
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_pregunta_horizontal_container, container, false);
addAnswerLayout(rootView, R.layout.fragment_pregunta_texto, getActivity());
setUpComponents(rootView);
//those 2 methods are about my app logic so I'm not going to talk much about them
setUpQuestionState(savedInstanceState);
readSavedAnswer();
return rootView;
}
public void addAnswerLayout(View rootView, int optionId, Context context) {
mContext = context;
RelativeLayout relativeLayout = (RelativeLayout)rootView.findViewById(R.id.pregunta_container);
LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
View newView = inflater.inflate(optionId, relativeLayout, false);
relativeLayout.addView(newView);
}
public void setUpComponents(View rootView) {
//next line: some heritage that you can ignore
super.setUpComponents(rootView);
respuesta = (EditText)rootView.findViewById(R.id.pregunta_respuesta_texto);
respuesta.setTypeface(UiHelper.getInstance(getActivity()).typeface);
respuesta.setTextColor(mContext.getResources().getColor(R.color.drs_gris));
...
}
次に、リスト ビューの CustomArrayAdapter に移動します。
- customArrayAdapter を次のように定義します
PreguntasVerticalArrayAdapter extends ArrayAdapter<Pregunta>
。「Pregunta」は、上記のロジックを持つ汎用フラグメントです。
- オーバーライドし
getViewTypeCount(), getItemViewType(int position), getCount(), getItem(int position) getView(int position, View convertView, ViewGroup parent)
ます。
同じ動作にgetView
従います。params で指定された位置のオブジェクトを取得し、「ビューホルダー」を再利用してデータを入力します。ここに私のgetView
:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
Pregunta pregunta = mData.get(position);
if (rowView == null)
rowView = createQuestionUI(pregunta, parent, position);
fillDataInRow((PreguntaUI)rowView.getTag(), pregunta, position);
return rowView;
}
private View createPreguntaUI(Pregunta pregunta, ViewGroup parent, int position) {
View rootView = null;
LayoutInflater inflater = (mPreguntasVerticalFragment.getActivity()).getLayoutInflater();
//you can ignore this part of the code ralted to Bundle.
Bundle args = new Bundle();
args.putLong(PreguntaUI.PREGUNTAUI_ID, pregunta.getIdpregunta());
args.putInt(PreguntaUI.PREGUNTAUI_INDEX, position);
args.putInt(PreguntaUI.PREGUNTAUI_TOTAL_QUESTIONS, getCount());
//internal method of "pregunta" to know what kind of question it is.
String tipo = pregunta.getTipo();
if (tipo.equalsIgnoreCase(PreguntaType.TEXT.toString())) {
rootView = inflater.inflate(R.layout.fragment_pregunta_vertical_container, parent, false);
Pregunta_texto pregunta_texto = new Pregunta_texto();
pregunta_texto.setArguments(args);
//LOOK AT THIS POINT!!!: I'm calling the same methods that I called in onCreateView fragment's method.
pregunta_texto.addAnswerLayout(rootView, R.layout.fragment_pregunta_texto,
mPreguntasVerticalFragment.getActivity());
pregunta_texto.setUpComponents(rootView);
pregunta_texto.setUpQuestionState(null);
pregunta_texto.readSavedAnswer();
//I'm adding the fragment to reuse it when I can
rootView.setTag(pregunta_texto);
}
else if ...
return rootView;
}
これですべてです... この時点で、CustomArrayAdapters と Fragments を扱った十分な経験があれば、おそらく理解できます! :D