How can I open specific position in listview? Let me tell what's my requirement and what I tried!
It's table of contents where when we are in page no 100, and when we click table of contents, it displays 100th page by highlighting. This is the requirment.
But in my case what's happening is, it keeps on scrolling and user needs to wait till the scrolling stops at 100th page. I used setSelection but it doesn't work.
So if I use smoothScrollingToPosition , it keeps on scrolling to stop at specific position. So my requirement is without scrolling directly to open specific page.
Below is the logic. I applied listview in constructor of the class Adapter.
In adapter,
#Override
public final View getView(final int position, View convertView, final ViewGroup parent) {
int type = getItemViewType(position);
if ((convertView == null) || (((Integer) convertView.getTag()) != type)) {
convertView = createView(position);
convertView.setTag(type);
}
final BaseTableOfContents node = getItem(position);
for(int i=0; i<mNodes.size();i++){
BaseTableOfContents nodes = mNodes.get(i);
if(okayToHighlightAnchorNode(nodes,i)==true){ //only when true, it lands to specific position.
Log.v("nodes","nodes"+okayToHighlightAnchorNode(nodes,i) + nodes.getText() + i);
// returnValue.getListView().setSelection(i); //but this is not working.
returnValue.getListView().smoothScrollToPosition(i,i); //this keeps on scrolling to specific page instead of directly landing to the specific page.
}
}
For a direct scroll use this below code:
getListView().setSelection(21);// anylistview.setSelection(21);
For a smooth scroll use this:
getListView().smoothScrollToPosition(21);//anylistview.smoothScrollToPosition(21);
You can do this -
yourListView.smoothScrollToPositionFromTop(position,offset,duration);
where position is where you want to scroll , duration is number of milliseconds taken to scroll, and offset is the distance in pixel
Related
The Problem
My way to add the view makes every fifth item to add the view when i only want one position to have this "Mängd" row.
Why Can i only edit listitems when they are visible on the screen.
The child will be static at 5 items even though i got like 20 item....
Is there any way to only say that item 1 will have this and not
position - firstvisibleposition
i think this is the problem with the listview
My code is not understandable at the time because of other things so i hope you get my problem anyways.
This is my main question
It seems like the thing i add to position 0 also happens to 6 and 12 Why is ListView this wierd ?
It's on swedish, but this is what i got with list view.
Every listview item has a empty Linearlayout that i add a view to when i press the down arrow button. the problem is that every fifth item gets this or i can only click on the first 5.
I dont get why they make ListView so complicated. i want to be able to get a child that is in the list without seening it!
CODE getView
public View getView (int position, View convertView, ViewGroup parent){
if (convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.view_meal_item_editable, null);
}
convertView.setOnTouchListener(new ItemSwipeListener(position,
getResources().getDisplayMetrics().density));
convertView.setClickable(true);
// Lookup view for data population
TextView food_item_name = (TextView) convertView.findViewById(R.id.food_item_name);
food_item_name.setHint("hello");
}
Where i add the view
View view = searchResultList.getAdapter().getView(position, searchResultList.getChildAt(position - searchResultList.getFirstVisiblePosition()), searchResultList);
LinearLayout extendedView = (LinearLayout)view.findViewById(R.id.extended_food_information);
View convertExtendedView = LayoutInflater.from(this).inflate(R.layout.change_amount_on_food_view, null);
extendedView.addView(convertExtendedView);
It's recommended to use a header view if you do this stuff only for the first element.
Otherwise it will be better if you add your extra view in getView() method, something like:
if(position==0){
// add extra view
} else {
// remove extra view if exist
}
Or you can remove the IF condition: if (convertView == null), so you will inflate a new layout each time, it will solve your problem but this is not good for list performance
I am having trouble with my code of putting a section header in my listview on more than one position.
this is my code,
to tell the adapter there are two types,
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
if (position == MainClass.addHeader) {
return 0;
} else {
return 1;
}
}
my getView method for the adapter,
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (position == MainClass.addHeader) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.heads, null);
}
} else {
// Normal views are handled by the adapter
convertView = super.getView(position, convertView, parent);
}
return convertView;
}
Now the problem is that, the value of static variable MainClass.addHeader is initially 0 so the section header shows at position 0 , and that is correct.
But as I scroll through the list view the value of MainClass.addHeader changes several times , each time the value of MainClass.addHeader is changed, the section header is added on that position. but the problem is that the section header is disappeared from the previous positions when appear on new position.
for example,
initially, the value of MainClass.addHeader is 0 and section header appears at that position.
I scrolls down, the value of MainClass.addHeader change to 8 , the section header appears at that position but disappears from 0 position and onwards.
How to make my section header not to disappear from previous positions ?
The header is ALWAYS at position 0. If you want to add a different element to other places in your list, you should just make a custom adapter, and adjust that particular element that way.
Bottom line, the header is designed to remain at the top of your list (you could use a footer for the bottom), and is not designed to be inserted into the middle of a list. You are trying to use it incorrectly.
If you are looking for a "Sticky Header" - ie. something that always remains on the screen, even when you scroll the list, you should create a unique view, and place it above your ListView in your layout. You shouldn't use a list header for this, as it is specifically designed to scroll WITH the list.
I have a list view which gets its contents from the web. on my onscrollListener, I have a check, so that if the firstVisibleItem is less than a thresh hold, I download more data. I also have checks to make sure I don't try to get more items when a previous get is still in progress.
But even after the get data request has completed, new data has been added to the data list, and notifyDataSetChange has been called, my firstVisibleItem is not updated (ie still shows the previus value that triggered the request for more data, even though the list has grown and the same row should now have a bigger number as its position). So in essence, once I hit the threshold for getting more data the first time, it will start a chain of events that will keep downloading more and more data until all rows have been retrieved.
I am using a LinkedList for my data. I need to be able to add items on both ends of my list.
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (moreMessages && !getMessagesInProgress && (firstVisibleItem < 10)) {
getMessages(NUM_MESSAGES_TO_GET, "after");
getMessagesInProgress = true;
}
}
When I successfully get the next chunk of data from the server, I add them it to my linked list using LinkedList.addFirst() in a for loop, call notifyDataSetChanged, and set getMessagesInProgress to false. My ListView is stacked from bottom.
UPDATE: When I say my firstVisibleItem does not update, I'm NOT talking about the view on the screen, I mean that the next time my OnScrollListener() gets called, the value passed in as firstVisibleItem is still the same as before, even though I have added 20 more downloaded items to the end of the list. so the row which was row position 1, should now be 21. (my list is stalked from bottom, its a message thread, so user starts at bottom of list and swipes down to see older messages which are at the top of the list. When firstVisibleItem < 10, I download 20 older messages and add to my linked list, so now the position of all the previous items should be +20. This doesnt happen and as a result, the first time firstVisibleItem becomes <10, my code continuously sends requests to the server for more messages)
I have not included my getView code, cuz this isn't a UI/visual issue. But here is the code from my custom BaseAadapter relating to "position"
#Override
public int getCount() {
return messages.size();
}
#Override
public Object getItem(int position) {
return messages.get(new Integer(position));
}
#Override
public long getItemId(int position) {
return position;
}
try in this way
when you add data in list then remove or update first visible item.
and In getView() of list, you are using if condition then write their else part too
get items from web view then add into list seems ok.and notifyDataSetChange() has been called in a correct way.
but I notice that you said
"my firstVisibleItem is not updated (ie still shows the previus value that triggered the request for more data " .
maybe you should check public View getView(int position, View convertView, ViewGroup parent) in your ListView adapter.It should like:
public View getView(int position, View convertView, ViewGroup parent) {
View item;
if (convertView == null) {
item = View.inflate(mContext, R.layout.your_list_item, null);
} else {
item = (View) convertView;
}
ListItem listItem=YouCustomList.get(position);
//update your date in UI like below
TextView textView=(TextView)item.findViewById(R.id.your_textView);
textView.setText(listItem.text);
return item;
}
so that it will update UI. if you do return when convertView!=null like :
//won't update!
if (convertView == null) {
item = View.inflate(mContext, R.layout.your_list_item, null);
} else {
item = (View) convertView;
return item;
}
then UI won't update until ListView destroyed and reconstructed.
The problem was that when new items get added to the list, the list would actually jump to the newly added, in order to maintain the same "irresistible".
I found a solution in another post that manually sets the new posotion of the view
int newFirstPosition = threadListView.getFirstVisiblePosition() + loopCount;
View v = threadListView.getChildAt(threadListView.getHeaderViewsCount());
int top = (v == null) ? 0 : v.getTop();
...
// for loop to add new data
...
messagesAdapter.notifyDataSetChanged();
threadListView.setSelectionFromTop(newFirstPosition, top);
I've got a GridView (Android). I would like to hide one of it's columns and then access to it's values.
Is it possible?
Update: based on your reply, I think it best you hold your data in a map, rather than using an invisible column...
Example:
HashMap<Integer, Integer> map_positionToId = new HashMap<Integer, Integer>();
map_positionToId.put(position, id);
int id = map_positionToId.get(position);
There is no easy setting to flip on gridview to make a column invisible that I am aware of.
However, below is a suggestion to try... It may take a bit of trial and error to pull off correctly:
This is the getView method for your gridView adapter:
public View getView(int position, View convertView, ViewGroup parent) {
//You want your if(convertView == null) code here.
//As we can't set visibility of a null object;
....
// Assuming u want to blank the 3rd column, in a 3 column gridview
if(position % 3 == 0)
convertView.setVisibility(View.INVISIBLE); //u can try gone too?
else
convertView.setVisibility(View.VISIBLE);
// rest of your code...
}
You might also play around with padding / margins, and view width, to get the desired effect if you are trying to push the invisible column off the screen.
I am retrieving a list of items from a URL and displaying them in a ListView using a customized ArrayAdapter. I display at most 25 results, but retrieve up to 26 from the URL because I want to display a "next" link if there are more than 25. I am trying to figure out a way to make the last item in the view just display the next link instead of the image and two TextViews that the other items display. Scrolling down, all the items show up the way they are supposed to, but the last item continues to look like the rest. When scrolling back up, every fifth item is blank (can tell it is still there because of the separating lines).
Inside getView:
if (position + 1 == limit) { // Limit = 26, corresponding position is 25
Log.e("Last Item", String.valueOf(position));
// Gone
image.setVisibility(8);
text.setVisibility(8);
// Visible
next.setVisibility(0);
} else {
if (item != null) {
Log.e("Other item", String.valueOf(position));
if (top_text != null) {
top_text.setText(item.getItemTitle(), BufferType.SPANNABLE);
}
if(bottom_text != null){
bottom_text.setText(item.getItemDescription());
}
}
}
return view;
In ddms, it is printing the "Last Item" tag only for the last item, and the "Other Item" tag for the rest, but the items aren't being changed based off the if-else. In the XML, next is set to gone so it doesn't need changed in the else. When I remove the if-else and leave only the code within the else, the list functions properly but I need the next link. Any ideas for the cause of the odd behavior? Please let me know if you need to see any additional code or need clarification on what is happening.
Please post full code of getView.
You return view; but what is view, is it convertView or inflated from xml?
Here is way how i get different view for last item:
1. create 2 layout, the first for normal items, the sencond for last item
2. in getView(int position, View convertView, ViewGroup parent)
View view = convertView;
if (view == null) {
LayoutInflater vi = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.xxx, null);
} else {
//check if view is not layout we need (based on position), we need inflate from xml
}
//set text ...