Hi, I ran into the same problem and I found a way to do this.
My problem was like you:
"I want to have a snippet for each item in the list because I want to separate some logic"
In my application, I must provide the ability to display user elements in vertical (listView) and horizontal (ViewPager) modes. In addition, I had to deal with 18 user elements and each logic, so the best approach was to reuse the fragments that I used for the ViewPager in the ListView.
I got this, but not the way you tried, I mean, I used my snippets like "ViewHolders":
- Define a fragment widget as class variables in each fragment.
- Create a custom ArrayAdapter and redefine:
getViewTypeCount(), getItemViewType(int position), getCount(), getItem(int position) getView(int position, View convertView, ViewGroup parent)
In getView I checked what type of layout I need before inflating the corresponding XML, creating a fragment, assigning a widget from XML to a fragment (using rootView.findViewById ), and setting a βtagβ with a new fragment. <ears>
What you see at this stage is that the fragments in the ListView were never attached to the Activity, but you got what you wanted: the logic is distributed in several parts and all the advantages of ListView (reusing rows, scrolling, etc. d.).
If you need, I can post some of my code, but you need to deal with "spanglish";).
UPDATED
The whole problem is that when you create a snippet that will be used with the ViewPager, usually all the "layout" and "setup" code is inside the onCreateView method, I mean:
- Get the view object that you are going to use (
View rootView = inflater.inflate(R.layout.fragment_question_horizontal_container, container, false); ) - Get widgets from above, define behavior, fonts, etc.: (
answer = (EditText)rootView.findViewById(R.id.answer_question_text); )
Up to this point there is nothing strange.
If you intend to use a snippet with the behavior described above, you must "imitate" the onCreateView call, fill in the data, and attach it to the View list.
Here's the trick: split the code in onCreateView in some methods that don't care about who calls them. An example of my 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);
Now go to the CustomArrayAdapter to view the list:
- Define your customArrayAdapter like this:
PreguntasVerticalArrayAdapter extends ArrayAdapter<Pregunta> where "Pregunta" is a common fragment with logic at the top. - Override
getViewTypeCount(), getItemViewType(int position), getCount(), getItem(int position) getView(int position, View convertView, ViewGroup parent) .
getView follow the same behavior: get the object for a given position in the parameters, reuse the "viewer" and fill in the data. Here is my 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 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; }
That's all ... for now, if you have enough experience with CustomArrayAdapters and Fragments, you probably got it !: D