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
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
Related Q & A:
- How to highlight a row in a listview?Best solution by Stack Overflow
- How safe is a career as a CNA in a nursing home?Best solution by Yahoo! Answers
- How do i find a profile of a person with a yahoo mail address?Best solution by Yahoo! Answers
- What does Politte Supply use: a sales journal, a purchases journal, a cash receipts journal or a cash disbursements?Best solution by Yahoo! Answers
- Redmon Company uses a sales journal, a purchases journal, a cash receipts journal, a cash disbursements?Best solution by Yahoo! Answers
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
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.