My ViewPager has 5 pages (which I try to make reusable), its custom PagerAdapter has a backing array with views, I initially add (inflate) them on startup, setting current page to middle page:
0 1 |2| 3 4
Now, on page scrolling I reuse one view from opposite end of the array populating it with new data (based on calendar dates) - I take the last view in array and move it to the beginning and vice versa depending on scroll direction. Then I populate it with new data.
Reusing views:
4 0 |1| 2 3 or
1 2 |3| 4 0 and so on ...
I move and update reusable page (here 4 or 0) in onPageSelected of ViewPager.OnPageChangeListener, which causes a short scroll animation freezing because of time-consuming routines.
That's why I decided to execute all the slow code in a separate thread and then populate subviews in the page calling View's post method. Ok, it works faster now, but a little freezing is present anyway.
The question is, how can I optimize/implement such scenario properly to achieve smooth dynamic paging?
Related
I have came across these type of questions a lot, But none of the answers solved my problem.
I am developing a mobile shopping application model. I have a custom ListView with an ImageView, and EditText(quantity), 2 Buttons for increasing and decreasing the quantity, 3 TextViews one for item Name and other two for prices and I am dynamically loading a number of Buttons for NetWeights based on the requirement through Java code and I am implementing it using CustomAdapter(Class) extending BaseAdapter and getView().
Problem 1:
When I use the condition if(convertView==null), setTag(holder) and getTag(), the dynamically loaded Buttons are getting duplicated and gets doubled in number.
Problem 2:
While scrolling the custom ListView I am loosing my data on 2 of the TextViews while the other TextView(name) is fine because in that TextView I don't Change data on runtime. On the other two TextViews(prices) I change the data on runtime using ButtonClicks(increase and decrease) where at that time when I scroll the two TextViews, it looses its content. Actually I had this same problem with the EditText(displaying quantity), I solved it using the TextWatcher by getting the value and passing it in an array and again setting it. I used the same technique (i.e) the TextWatcher for the TextViews But that did'nt Help. I also tried removing the TextWatcher and setting the text with the array and adding TextWatcher. Still I am loosing my content in those TextViews
Any Suggestions??????
Problem 1:
While using ViewHolder (setTag(), getTag()) we will be reusing the views.
For example: Let's say we have 10 listview items and the screen can display 3 items at a time. Lets say we add 2 buttons to list item 1. First time when we load the listview we will see two buttons. Lets say now we scroll down and come back to the list item 1 again, as we are reusing the views, we already have 2 buttons and if we have the code to add buttons using getTag() then 2 more buttons will be added. I think this may be causing the issue of button duplication. To add little more information, list item 1, list item 4, list item 7 and list item 10 will all use same view, as our screen in this example can display just 3 items.
Problem 2:
One idea is to store all these text values in the arrayList.
For example, lets assume we have one textView inside each list item that can be incremented/ decremented. Set textWatcher on this textView and whenever text changes add it to the arrrayList using 'position' as the index. Inside getView method when you do getTag() try to set the textView using previously stored text (that was stored inside the arrayList)if exists.
I am displaying data: 3 fields for each record, 3 ListViews are currently displaying the corresponding data.
I did this so that I could have columns for the data.
The problem is: When you have enough data that scrolling is neccassary, I need to sync the ListViews.
Can anyone point me in the right direction? Or is there a better solution for displaying this data in column format?
Thanks
You could try registering a scroll listener on each of the lists (http://developer.android.com/reference/android/widget/AbsListView.OnScrollListener.html)
Then update the position of the other 2 lists whenever that gets called back (either http://developer.android.com/reference/android/view/View.html#scrollTo(int, int) or http://developer.android.com/reference/android/widget/AbsListView.html#smoothScrollToPosition(int))
I wouldn't recommend this though as it will not scroll smoothly or at the same time!
As Ken mentioned in a comment a single list with a custom view would work much better - consider a LinearLayout with a weightSum of 3 and your 3 views (or sub-layouts) all having a weight of 1, to get 3 equally spaced columns.
Before I start, similar question (of mine) exists, I'd like that one to be deleted since I didn't explain my point well there, but not this one. Thank you.
First of all, I have no code, this is only a concept that I can't figure out. But it's interesting (at least to me).
You all know how MSWord works. You write stuff. Then, when you fill a page it will create a new page and start writing on that page. If you paste some more text to the first page, everything will be pushed down. If you delete a large chunk of text on a page, it will suck up some of the text on the previous page. If you're dealing with e.g. pictures and you have one on top of a page, reducing it's size my cause it to get sucked up to the previous page, if there is enough room for the reduced version of the picture.
Now that you're thinking this way, I want to transfer that concept into Java Swing. Pages are JPanels, and pictures and chunks (or lines) of text are JPanels fitted onto the page JPanel.
I have come up (okay, I lied, I have some code, but it's a mess and it doesn't work anyway) with a method using a Filler, which doesn't work in all cases. If you want to know why, read between the two lines, otherwise just skip it.
So, the structure itself is easy to replicate, but maintaining it is a pain in the neck. You see, there are two main types of events that can occur:
a) height of the page content has increased
b) height of the page content has decreased
By using a Filler as the last component of a page, and having a componentAdapter (componentResized) attached to it, you can monitor those changes.
These changes can further be dividet into:
a) element is added/removed to/from page
b) height of the element has increased/decreased
Taking those events into consideration many things can happen. Skipping the simple cases, look at this example:
Page 1:
{element 1
blabla
blabla}
{element 2
blabla}
{element 3}
{element 4
blabla
blabla
blabla
blabla}
{free space
---
---
---}
/
Page 2:
{element 1
blabla
blabla
blabla
blabla}
{element 2
blabla
blabla
blabla
blabla}
{element 3}
{element 4
blabla
blabla
blabla}
/
Page 3:
{element 1}
{element 2}
{element 3}
{element 4}
{element 5}
{free space
---
---
---
---
---
---
---
---
---}
Each page has a height of 15 rows. Look now what happens if you reduce the height of the element 1 of the second page by one row. It will become 4 rows high, making it fit to the previous page, being sucked up. That will create 5(1 deleted row + 4 sucked up rows) rows worth of free space on the second page. That will suck up all the five elements on the third page and leave the third page blank (which should now be deleted).
The reason this wouldn't work is because upon deletion, a listener is triggered for the second page and it has to both push the top element up, and suck up the elements from the previous page. Since it's all done in a listener, I have to wait for it to execute in order to register visual change in my program. Since it has to change two thing on a page, it comes to somekind of listener chaos. Page height is reduced twice but is registered only once and in the end I can fully move only thr top part or the bottom part, or a single component on each side. This isn't really a good explenation, but if you understand how swing works, you should be able to connect the dots yourself.
As I mentioned before, I have written the code for that, but it's long and hard to follow, and I can post it here, if anyone shows the desire to see it. And I'm talking about SSCCE itself. It really can't be shortened into couple of 10s of rows of code.
What I would want is to skip writting an algorithm that would maintain the structure of the "document" and move all the elements around, since it's a really complicated thing to do, taking all the numerous cases.
What I want is an alternative and I'm asking you if you have any ideas. One thing that came to my mind is having a component similar to JPanel. It would have fixed height-parts that can be populated with other components, and between them fixed height-parts that are unpopulable(?) or "solid".
Way it would work would be that everytime you add something to populable(?) parts, they would be automatically rearanged. If something doesn't fit to the current populable part, it's just moved to the next one (similar to how verticall box layout works, adding one thing to a spot pushes all the others down), but skiping the solid part.
Since I would also have to be able to tell in which populable part a certain component is, I don't know if creating a such structure is possible in Java swing.
Well, any advice is welcome, external libaries included.
Just keep in mind that this whole document is document with pages that would be placed one after another in a JScrollPane's viewport, and that is the only limit to what it should look like.
Let the layout do the work: add() instances of JPanel, each having its own preferred size based on content, to a Box having a vertical layout. Put the Box in a JScrollPane, optionally implementing Scrolable. Use the scroll pane's row and column headers as needed; JTable is an example. You can remove() a panel from the Box, revalidate() and repaint() as required.
Addendum: The initial answer addressed only the view aspect of the problem. It may help to separate the model and view more rigorously, as the text components do; remove content from the model and signal the view to update itself accordingly. To achieve this, several common approaches to implementing the observer pattern are mentioned here.
I am working on an Android project. In my app,I have 3 tabs. As the Activities I use have many things in common (e.g. ListView), I use inheritance as below:
List a is generated by my SAXHandler and it creates a new list in startDocument ().
I have a testcase of which the list in A_Activity has 7 items and B_Activity has 3 items. When my app starts, I have no problem clicking on all the items shown in A_Activity. After I click B_Activity and switch back to A_Activity, I also don't have any problem clicking on the first 3 items; however, if I click on the fourth items, I get
java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
If I increase the number of items on B_Activity to 4, I get the same exception with 3 replaced with 4. So, I am certain that the cause of it is that when I jump back to A_Activity from B_Activity, the list in A_Activity is still referring to B_Activity's.
Your advise will be highly appreciated. Thank you!
You can do simple thing just clear the adapter data and call notifyDataSetChanged of an adapter class each time you switch activity.
Tab is started with 0. So start with 0.
tabhost.setCurrentTab(0);
1 means->0
2 means->1
and so on
I have a JList that gets filled up with values with a DefaultListModel.
By entering a name and pressing on a button it gets listed in the JLlist (vertical wrap).
But the odd thing is they get placed underneath each other properly (8 items).
But starting from 8 items suddenly al the items get listed right of it again (like shown below).
The JList itself is more then big enough, so what could be causing this most odd behaviour?
All the items below get stored in a list and are being added to the default list model.
1 9
2 10
3
4
5
6
7
8
But the proper output should be everything listed underneath each other.
Read the JList API and follow the link to the Swing tutorial on "How to Use Lists". There it will explain about the "setLayoutOrientation" method which supports 3 values:
Vertical
Vertical Wrap
Horizontal Wrap
You must have set this property somewhere in your code.