I have a ScrollView->TableLayout->TableRow
Inside the TableLayout thare are some TableRows visible and some gone. Its because clicking a TableRow, some other rows below it will become VISIBLE.
Its everything ok now, except that the rows that I turned VISIBLE may not appear in the screen because they arent in the scrollview display area.
I wanna display them without the user scroll, so I need to get the row position to do the scroll.
The problem is, the Draw inst immediately, so I cant get the position. I tryed invalidate and postinvalidate but inst working.
What should I do?
EDIT: What I realy want is a way to update positions and sizes of my views.
I found the solution here (Android) Why won't invalidate() update my buttons immediately?
Do you know where the newly-visible cells are going to be drawn? If you have, say, the cell immediately above it (which would make sense if you're adding the rows with addView()), you can get the bottom position of the cells immediately above your newly-visible cells (with getChildAt() then calculating the vertical offset), and then use scrollTo() (or the sexier smoothScrollTo()) to scroll to that position - that should scroll so that the new row is at the top of the screen. Highlighting the new row somehow would also help the user see that this is the new content.
if you can calculate the rowHeight. or the height of each row. then you may be able to calculate the position where the row (view) may appear.
and you can call the
scrollView.scrollBy(x, y)
or
scrollView.scrollTo(x, y)
in the scroll view.
Related
Ok, I will try to describe the problem as best as I can.
I have a RecyclerView and a bunch of ViewHolder items.
Each ViewHolder has a button.
My goal is, to display a PopUpWindow right under the button that I click.
I set up the listeners, and I know 100% that I am touching the item that I intended to touch.
The problem is when I touch items that are way down the RecyclerView things get really weird.
Nothing is positioned within the screen boundaries, so when I call myPopUp.showAsDropDown(myButton) so if the item that I clicked on is the 1st or 2nd one let's say (where I have 2 ViewHolders occupying the screen at one time) I'm able to see the PopUpWindow normally. But, if I click on an item that isn't visible unless if I scroll down, the PopUpWindow is getting displayed but it's off the screen boundaries, which I kinda understand why but I don't know how to fix it, is this a bug?
Any help would be appreciated, I hope I was clear, If I wasn't I will expand, thanks!
UPDATE:
I Logged the coordinates of the View item when scrolling it into the screen in the middle, it is like 1200 y-value, where my screen is only like 1400.
So I guess my question can be rephrased into, "how can I make sure that view items in the recycler view give me accurate absolute coordinates based on where they are on the screen, instead of where they are in the recycler view?
Ok so after more testing, I see that when I click on the item, it gives correct absolute coordinates, then when after scrolling upwards where the 2nd item is now the 1st (visually) I click on it, and it gives a similar absolute y-value, which is good. But when I scroll to the 3rd item it gives me the original y-value of that item which is way higher than expected.
The view you pass for the popup will decide the popup location.
Now try with
myPopUp.showAsDropDown(myButton, x, y)
with x and y got from location calculation:
int[] originalPos = new int[2];
itemView.getLocationOnScreen(originalPos);
//or view.getLocationOnScreen(originalPos)
int x = originalPos[0];
int y = originalPos[1];
I have been trying to halt the vertical movement in the RowsSupportFragment. I have two rows and I want them to be displayed all the time on fixed positions.
In android TV whenever the focus moves vertically in Rows, next row moves up and leaves its original position. I want it to be fixed vertically.
Please help me solve this if there is any way to do this?
Do you want to keep the focus point fixed?
The following code will make the position of focus fixed to first row:
// Item alignment affects focused row that isn't the last.
getVerticalGridView().setItemAlignmentOffset(0);
getVerticalGridView().setItemAlignmentOffsetPercent(0);
// Push rows to the top.
getVerticalGridView().setWindowAlignmentOffset(0);
getVerticalGridView().setWindowAlignmentOffsetPercent(0);
getVerticalGridView().setWindowAlignment(VerticalGridView.WINDOW_ALIGN_LOW_EDGE);
Check the following link for more details:
https://developer.android.com/reference/android/support/v17/leanback/widget/VerticalGridView
I've been trying to work out how to calculate the y-position of scrolled content inside an Android ListView. The consensus seems to be that Android simply doesn't give you this information and you have to work it out by doing all sorts of calculations based on the getChildAt(0).top and getFirstVisiblePosition() methods.
My question is to try to understand why Android doesn't give you this information. It would seem to that the the list view must actually know this value somehow in order to draw the scrollbars. Or at least know it as a percentage? The ViewPager's onPageScrolled() method seems to do the same thing. And it's a trivial matter in iOS as well.
ListView is not same as ScrollView as you thought of.
For example, if you have 10 items with use 2048px hight. If you wrap them in scroll view, the inside content is 2048px height. However, in ListView, the 10 items will be populated dynamically. It is always in the displaying area, thus the scrollY = 0.
If you really want to calculate the ScrollY of ListView, you might need to take care of it by yourself. You can getFirstVisiblePosition() to get the index of the current top visible item. And consider the height of each list item and list divider, you might be able to get the total scrollY value.
I have a ListView which has overlayed on top of it another view which I call a Header. This header can be of various heights.
On ListView's dataset, I insert in a blank row, and programmatically set the height of this row to be the height of my Header view. This way when the ListView loads, the row at position 1 (the actual first row of data) is lined up to the bottom of the header. I do this so I can set the Header view as partially transparent and when the user scrolls they see the rows of data mix with the transparency of the Header view.
Now I have one use case where I can navigate to this list and a given row will be selected. What I've done is call setSelection with position X. This will automatically scroll my ListView so that the top of row X is at the top of the list. However, my Header view still obscures this. To compensate I call scrollTo. These two pieces are something as such:
listView.setSelection(selectedRowPosition);
if(hasHeadersEnabled()) {
listView.scrollTo(-headerView.getMeasuredHeight).
}
When I call these lines of code, my ListView looks as I would expect. The selected row's top is to the bottom of my HeaderView. The problem I run into is that as soon as a user touches the ListView, the scroll position jumps so that the selected row's top is at the true top of the ListView (aka the Header view's top).
My question is, after you setSelectedRow on a ListView, does the ListView always expect that row's top to be the ListView's top when it starts consuming the onTouch events for scrolling? Is there another way to accomplish what I'm hoping to do with this code? I've tried scrollTo and scrollBy and both have the same effect.
So I should have looked at the API harder. Found the answer to my question.
I need to use setSelectionFromTop instead of the combination of setSelection and scrollTo. Here is the sample code:
listView.setSelectionFromTop(rowPosition, headerView.getMeasuredHeight());
I have a ListView in my Android application. The individual views in the list are a little bit smaller than the size of the screen.
I want the list to always show one item centered in the screen, with just a small sliver of the previous and next items showing above and below it.
When the user scrolls, I need to reposition the child view at position 0 or 1 (depending on which way they are scrolling). Currently I am doing this by calling "setSelectionFromTop" in my onScrollStateChanged method. This works, but the transition is immediate, not smooth. It is jarring and confusing in a lot of cases.
What's the best approach to fixing this? I want to animate the process of scrolling the list into the position I want, but I can't find any methods in ListView or its superclasses that let me directly control the scroll position of the entire list.
I think I could animate it using multiple calls to setSelectionFromTop(int position, int y) with progressive values of y, but I don't know how to determine the initial value of y. Is there some way to get that by interrogating the view object at the designated position?
Another challenge I have in front of me is that I want to animate the removal of an item from the list - by having it either disappear or slide away to the left, and then having the surrounding views move up and down to fill the space. Is there a straightforward and reliable way to do this with a ListView? Should I just give up on the ListView and write the whole thing as a custom view from scratch?
Thanks.
This definitely should be possible. Does smoothScrollToPosition() work?
Otherwise, you can try simulating the touches using TouchUtils.