How to refresh a listview within a Fragment?

Adding a View makes a ListView within a fragment to refresh

  • This might be a little bit hard to explain, so the best way I can think of, is providing you a Video showing up the issue. In the Video I show myself scrolling listview, and after 5 seconds, a View is created and added inside that holder in the bottom. In that moment, listview is refreshed. http://tinypic.com/player.php?v=vpz0k8%3E&s=8#.U0VrIvl_t8E The issue is the following: I've an Activity with a layout that consists of a: Fragment (above RelativeLayout), match parent, match parent. RelativeLayout, as wrap content. The fragment displays a ListView with animations for every row. If I add a View on the "RelativeLayout", it makes the fragment to readjust to the new size, as it's set above this RelativeLayout, so every Row is rebuilt again. Do you guys think in any way to avoid this? EDIT: Sourcecode: https://bitbucket.org/sergicast/listview-animated-buggy

  • Answer:

    Don't start the animation if the layout process for the added footer view is running. The end of the layout process can be determined using the ViewTreeObserver (the start obviously starts with adding the footer view): hand.postDelayed(new Runnable() { @Override public void run() { ViewTreeObserver viewTreeObserver = holder.getViewTreeObserver(); viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @SuppressWarnings("deprecation") @Override public void onGlobalLayout() { holder.getViewTreeObserver().removeGlobalOnLayoutListener(this); mIgnoreAnimation = false; } }); mIgnoreAnimation = true; holder.addView(viewToAdd); } }, 5000); Add this method to your Activity: public boolean ignoreAnimation() { return mIgnoreAnimation; } And check it in your Fragment: @Override public View getView(int position, View convertView, ViewGroup parent) { Context context = FragmentTest.this.getActivity(); TextView tv = new TextView(context); tv.setText("Pos: " + position); tv.setTextSize(35f); if (runAnimation()) { Animation anim = AnimationUtils.loadAnimation(context, R.anim.animation); tv.startAnimation(anim); } return tv; } private boolean runAnimation() { Activity activity = getActivity(); if (activity != null && activity instanceof MainActivity) { return ! ((MainActivity)activity).ignoreAnimation(); } return true; } Of course the whole Activity - Fragment communication can be improved considerably but the example gives you the idea how to solve the problem in general. While it prevents the animation from being started, it doesn't prevent the ListView from being refreshed although the user won't notice. If you are concerned about performance you can improve the Adapter code by re-using the views: @Override public View getView(int position, View convertView, ViewGroup parent) { Context context = FragmentTest.this.getActivity(); TextView tv = null; if (convertView != null && convertView instanceof TextView) { tv = (TextView) convertView; } else { tv = new TextView(context); }

Sergi Castellsagué Millán at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

Yes, I can think of a possible way to solve this. Your problem is: You have set layout params of your holder to wrap_content. By default, when it has no content, it is "zero-sized" somewhere in the bottom and invisible to you (not invisible in terms of Android, though, sic!) When you add a View to this holder, the framework understands, that the size of your holder container is different now. But this container is a child of another container - your root RelativeLayout, which, in turn, contains another child - your <fragment>. Thus, framework decides, the root container alongside with its children should get laid out again. That's why your list gets invalidated and redrawn. To fix the issue with list getting invalidated and redrawn, simply specify some fixed layout parameters to your holder. For example: <RelativeLayout android:id="@+id/holder" android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" > </RelativeLayout> That will prevent the list from being redrawn. But in that case you'll get your holder displayed from the very beginning.

Drew

Yes. This is the expected behavior of RelativeLayout You are adding the ListView Fragment and TextView into a RelativeLayout, So whenever there is a change in the child view dimension, will affect the other child in the RelativeLayout. So here when you add a new TexView , the other child Fragment is affected even though its height is match_parent. You can fix this only by changing the parent layout to LinearLayout.

Libin

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.