Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I finally found a working solution:</p> <p>My TreeElement class looks like this:</p> <pre><code>public class TreeElement { private int id; private TreeElementType type; private String name; /** * List that holds a set of all the children tree elements. */ private List&lt;TreeElement&gt; children = new ArrayList&lt;TreeElement&gt;(); /** * List that holds a set of the courses associated to the TreeElement. * * @see Course */ private List&lt;Course&gt; courses = new ArrayList&lt;Course&gt;(); public TreeElement() { this.type = TreeElementType.NODE; this.children = new ArrayList&lt;TreeElement&gt;(); } public TreeElement(int id) { this(); this.id = id; } public TreeElement(int id, String name) { this( id ); this.name = name; } public TreeElement(int id, TreeElementType type, String name) { this( id, name ); this.type = type; } public int getId() { return id; } public void setId(int id) { this.id = id; } public TreeElementType getType() { return type; } public void setType(TreeElementType type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List&lt;TreeElement&gt; getChildren() { return children; } public void setChildren(List&lt;TreeElement&gt; children) { this.children = children; } public void addChild(TreeElement child) { this.children.add(child); } public void addChildren(List&lt;TreeElement&gt; children) { this.children.addAll(children); } public List&lt;Course&gt; getCourses() { return courses; } public void setCourses(List&lt;Course&gt; courses) { this.courses = courses; } public void addCourse(Course course) { this.courses.add(course); } public void addCourses(List&lt;Course&gt; courses) { this.courses.addAll(courses); } } </code></pre> <p>These TreeElements thus generate a hierarchical tree. Each TreeElement can additionally hold some courses I want to show in the tree.</p> <p>The fragment holding all the pager with the pages is this one:</p> <pre><code>public class BrowserSectionFragment extends Fragment { private BrowserFragmentPagerAdapter mAdapter; private ViewPager mPager; private List&lt;Fragment&gt; fragments = new Vector&lt;Fragment&gt;(); public BrowserSectionFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_browser, container, false); /* * Add the root TreeElement-fragment, holding the categories of lowest * level. */ fragments.add(new BrowserPageFragment(this,TreeContainer.getTreeElement(TreeContainer.ROOT_ID))); mAdapter = new BrowserFragmentPagerAdapter(this.getFragmentManager(), fragments); mPager = (ViewPager) view.findViewById(R.id.pager); mPager.setAdapter(mAdapter); mPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageScrollStateChanged(int arg0) {} @Override public void onPageScrolled(int arg0, float arg1, int arg2) {} @Override public void onPageSelected(int arg0) { while (arg0 &lt; fragments.size()-1) { fragments.remove(fragments.size()-1); } /* * notify the adapter of the changes being made * causes the adapter to check all elements, if they are still in the * list of fragments */ mAdapter.notifyDataSetChanged(); } }); return view; } /** * Adds a new fragment to the fragment manager. The data is taken from * the children list of the TreeElement. * * @param clickedElement */ public void addFragmentFromElement(TreeElement clickedElement) { fragments.add(new BrowserPageFragment((this),clickedElement)); mPager.setCurrentItem(fragments.size()-1, true); } } </code></pre> <p>Now I need a PagerAdapter, in this case a FragmentStatePagerAdapter, to organize the Fragments:</p> <pre><code>public class BrowserFragmentPagerAdapter extends FragmentStatePagerAdapter { /** * List that holds all the fragments which are currently accessible * through the Pager. */ private List&lt;Fragment&gt; mFragments; /** * Constructor that initializes the list of fragments. * * @param fm FragmentsManager * @param fragments */ public BrowserFragmentPagerAdapter(FragmentManager fm, List&lt;Fragment&gt; fragments) { super(fm); mFragments = fragments; } @Override public Fragment getItem(int position) { return mFragments.get(position); } @Override public int getCount() { return mFragments.size(); } @Override public int getItemPosition(Object item) { /* * See if fragment is still in the list. * If yes, the position in the list is returned, if not, POSITION_NONE, * which causes the Pager to delete the related view. */ Fragment fragment = (Fragment) item; int position = mFragments.indexOf(fragment); if (position &gt;= 0) { return position; } else { return POSITION_NONE; } } } </code></pre> <p>Finally I implemented a PageFragment which is showing a ListView:</p> <pre><code>public class BrowserPageFragment extends ListFragment { public static final String ARG_ELEMENT_ID = "element_id"; TreeElement element; BrowserSectionFragment frag; Context context; public BrowserPageFragment() { super(); } public BrowserPageFragment( BrowserSectionFragment frag, TreeElement element ) { this(); this.frag = frag; this.element = element; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { /* Creating an array adapter to store the list of countries **/ BrowserListAdapter adapter = new BrowserListAdapter(inflater.getContext(),element); /* Setting the list adapter for the ListFragment */ setListAdapter(adapter); return super.onCreateView(inflater, container, savedInstanceState); } @Override public void onListItemClick(ListView l, View v, int position, long id) { Object clickedElement = l.getAdapter().getItem(position); if (clickedElement instanceof TreeElement) { frag.addFragmentFromElement((TreeElement) clickedElement); } else if (clickedElement instanceof Course) { /* * Start a new fragment which shows a detail view of the course. */ Course course = (Course) clickedElement; int courseId = course.getId(); CourseContainer.setCourse(courseId, course); Fragment fragment = new DetailsFragment(); Bundle args = new Bundle(); args.putInt( DetailsFragment.ARG_COURSE_NUMBER, courseId); fragment.setArguments(args); getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.container, fragment).commit(); } } } </code></pre> <p>To make it complete, my custom ListAdapter looks like this:</p> <pre><code>public class BrowserListAdapter extends BaseAdapter { private final LayoutInflater mInflater; TreeElement element; List&lt;Object&gt; elements = new ArrayList&lt;Object&gt;(); public BrowserListAdapter(Context context, TreeElement element) { mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.element = element; elements.addAll(element.getChildren()); elements.addAll(element.getCourses()); } @Override public int getCount() { return elements.size(); } @Override public Object getItem(int position) { return elements.get(position); } @Override public long getItemId(int position) { Object item = elements.get(position); if (item instanceof TreeElement) { return ((TreeElement) item).getId(); } else if (item instanceof Course) { return ((Course) item).getId(); } return -1; } @Override public View getView(int position, View convertView, ViewGroup parent) { View itemView = (View) mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); bindView(itemView, position); return itemView; } private void bindView(View itemView, int position) { Object item = getItem(position); String text = null; if (item instanceof TreeElement) { text = ((TreeElement) item).getName(); } else if (item instanceof Course) { text = ((Course) item).getTitle(); } itemView.setId((int) getItemId(position)); TextView title = (TextView) itemView; title.setText(text); } } </code></pre> <p>Maybe this solution helps somebody. The only remaining problems here are:</p> <ul> <li>The constructor of BrowserPageFragment has a constructor with arguments, which is not nice.</li> <li>When changing the orientation the Pager jumps to the first page.</li> <li>The back-button does not go to the previous page.</li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload