I'm actually making an application using a ViewFlipper to display 3 differents custom views. These views are, for each one, in a ScrollView (putting the ViewFlipper in a single ScrollView isn't making my onFling gestures really efficient). And i'm actually trying to synchronize the three Scrollbars position. At this point using a single ScrollView would have been easier but i trying to not use this solution.
I'm using a ScrollListener for each ScrollView to set the others ScrollView scroll position like in this thread : Synchronise ScrollView scroll positions - android.
The problem is that this method will works but the first time. When i'm on a ScrollView, the two others are not drawn already and their height is null. So setting their scroll position isn't working.
/*Instanciate ScollViews*/
scrollViewLeft = (ScrollableScrollView) findViewById(R.id.scroll_prev);
scrollViewCenter =(ScrollableScrollView) findViewById(R.id.scroll_current);
scrollViewRight = (ScrollableScrollView) findViewById(R.id.scroll_next);
/*Fill views with events*/
setDayEvents(calIns.getPrevCal(),leftDayView);
setDayEvents(calIns.getActualCal(),centerDayView);
setDayEvents(calIns.getNextCal(),rightDayView);
scrollViewLeft.setScrollViewListener(this);
scrollViewCenter.setScrollViewListener(this);
scrollViewRight.setScrollViewListener(this);
So finally my question is, should i use another method to find the scroll position of the two others views ? Or can i force the view to be drawn in a ViewFlipper ?
Thanks :)
Clement.
Try saving the positions in global variables before you change the views and then just apply it to your current view.
Thanks Egor for having answered. I think it is a good idea. I already have a Singleton to handle variables. So i add the variable position with getters and setters.
The probleme here is than even if I override the method "onSizeChanged" in my custom ScrollView, this will apply only for the first view shown.
PS: I'm still starting on Android development and I don't really know how to handle with
interactions on views when they aren't ready (for example getting width when they are not drawn yet).
Edit 1 day later :
Ok i found what was the problem, it is because the size of my views inside the scrollviews wasn't defined (the scrollview was drawn before the view inside it). So by setting the scroll inside the "onSizeChanged" method of the views works well.
Related
Everyone knows that GridView does not supports headers and footers like a ListView.
There is a few ways to implementing this:
Use a ListView and form columnt manually via ViewGroups. It not works for me, because it's require a lot of layout operations like measuring and layouting, and it's difficult to implement draw selector on top.
Use special adapter. It works fine with a footer: we should fill last cells with a Space and manually insert after them out footer with width that equals GridView width. But this not works with headers: although header is stretched, next cells float on it.
Use a GridLayout. GridLayout is good, but what about performance with 500-1000 cells? AdapterView supports caching and reusing Views, as far as I know, this is not possible with GridLayout.
Extend GridView and write custom class, that allows to draw a header before the grid content. It's difficult, but it's should work very fast. Let's try to figure out how to do this:
Measure the header. It's very simple, I have not questions about this.
Layout header in the top of the grid. We also should consider with scrolling position to allow move header with whole grid content, so my first question is: how to know where bottom border should be located while scrolling?
Layout whole grid content after the header. How to do that? I've newer do this before.
Dispatch draw to the header view too and resolve overscrolling effect if it's not work well.
Handle the scroll event and refresh header position.
So what you can suggest me? How to do header offset? Is it right to invoke relayouting with every scroll event?
I searched an answer on a same situation with a GridView (but for a FooterView).
I've read attentively your suggestions and some from other websites. I had the same reflexion. I found a simple way as your tip: "Use special adapter. It works fine with a footer..." and this answer by #RaulSoto helped me a lot. But when I tried to update my gridview, I had a NPE, because my footer was not like the layout of my items and I had a custom filter which recalculated the getCount() method, but without understand that another view was added.
Finally, I found only solution which works: a custom class.
Create your own class as you said: "Extend GridView and write custom class" but don't extend GridView. You should extend with ListView and measure the entire width, the column width and the number of columns. I think, it's less difficult that to extend GridView, calculate the height of the header view and move it as you move your gridview or refresh the header each time you handle a scroll event..
I searched to do it in this way and I took this little project on GitHub: HFGridView by Sergey Burish. It was exactly what I need, no more.
I only added a custom attrs file in my app and customize a bit his project to have the expected result (especially, it was to have one column in portrait, two in landscape mode, refering to the numColumns attribute in my layout).
And when I try, just for test, to add a HeaderView and refresh the content with adding new items, the header view stays at the top of my gridview list, without refreshing himself.
So, I think you should search to create your class as GridView extends ListView. Refer you to the HFGridView by SBurish, it is very simple to understand how it does.
Hope this helps you with your purpose.
This is one of the intermediate screens in the app.
I'm using a viewflipper.
I'm setting this view using vf.setDisplayedChild(9); where vf is ViewFlipper object.
Referring to above screen-shot, if I reach upto country field (which I'm checking through isFocused()), the whole view should scroll by some pixels (equal to keyboard height).
If I hadn't used viewflipper, then I would have tried something like scrollTo(x, y).
But how do I scroll in viewflipper.
Any help appreciated.
You could place a ScrollView as the view inside of the ViewFlipper.
The only problem I think you may still run into is that the keyboard should automatically shift things up (in my experience it doesn't function properly while in fullscreen though). I'd try displaying that screen without the fullscreen enabled and you may find that your behavior is handled automatically.
I have a working example of a grid that allows items to be reordered using long touches to active a drag-n-drop. All is working well if the items are simple Views e.g. TextView or ImageView but if the items are LinearLayouts only the layout itself is displayed.
I've been using Tom Quinsn's grid (thanks Tom!!!) from this posting:
Android Gridview drag and drop example
I can get LinearLayouts to work if I derive my own LinearLayout class and override onLayout(), but this forces me to hardcode the positions of the child controls in the layout within this function.
Ideally I would like to be able to define the item layout within an XML file and inflate them before adding them to the Control that handles the grid. I'm guessing that for some reason the framework is not calling the layout function for the children contained within the DraggableGridView view as defined in Tom's code but I can't understand why that is.
I am developing my own Drag and Drop app with good help from this link. You may compare the code with the one from Tom Quesinsn. It also gets the different children of a GridView and add them as "drop targets" that accepts drops on them and copy the Image of the View you are dragging.
This is a known problem with the DraggableGridView that -- unfortunately -- I haven't gotten around to fixing. When I wrote DGV, I didn't entirely grasp how views were laid out. You might try having DGV measure each child before laying it out. Adding something like:
getChildAt(i).measure(MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY));
before the layout on this line:
getChildAt(i).layout(xy.x, xy.y, xy.x + childSize, xy.y + childSize);
I need to implement a UI like this:
In the above screen row needs to be scrolled horizontally and columns need to be scrolled vertically.
I have not used Gallery as It is being deprecated. Here are some scenarios which I have tried:
1. Combination of GridView and ListView.
2. Combination of ListView and Horizontal ListView(Custom Component).
Option 1 did not work for me but I could make it with option 2.
With option 2 perfomance is not good.
Solution: I am thinking of implementing 4-5 horizontal listviews inside scrollview with Gestures so that I can handle the vertical swipe thru code or by subclassing the ScrollView and overriding the onScrollChanged method.
But I am looking for some more optimized solution.
Any help is appreciated.
Thanks
Use webview and push the content into it through JS hooks.
I have gone with my solution if anyone can suggest a better solution then obviously I will go with it:
Solution:
Implemented 4-5 horizontal listviews inside scrollview with Gestures
and handled the vertical swipe thru code or by subclassing the
ScrollView and overriding the onScrollChanged method.
I have a text view where in i have to keep ages between 1-99. I also have two buttons ^ and v(i mean up and down arrows) on clicking them the values of the age should smoothly scroll to next or previous value.
I have been trying different ways but couldnt achieve smooth scrolling. Can anyone please give me any idea of how to achieve the task.
I think the easiest way is to simply put the TextView within a ScrollView, and let the arrows interact with the ScrollView, by using things like the fling method and playing around with the velocity parameter to suit your needs.
Use the animation framework.
When pressing down, start the 'down'-animation.
When pressing up, start the 'up'-animation.
Read more about animation here: http://developerlife.com/tutorials/?p=343
View animation is not much matured and hence i am noy sure if that can be used for moving the views.
Please find the description below:
Another disadvantage of the view
animation system is that it only
modified where the View was drawn, and
not the actual View itself. For
instance, if you animated a button to
move across the screen, the button
draws correctly, but the actual
location where you can click the
button does not change, so you have to
implement your own logic to handle
this.
Source
To scroll smoothly you can try using the scroller component.
Reference
What you would need to do is pass the duration of the scroll in the constructor and then use the property
setFinalY(int newY)
to increment the counter position by 1 unit (equal to the height of the item).
Please let me know if that helps!