How to Identify a ListViewItem to Update a Single Row - android

I have a ListView displays information about an object. When I click a ListView Item, I open an Activity that let's me manipulate parameters of the object held in the adapter. These parameters are updated and stored remotely.
When I return to the ListView (via the back button), I want to update the ListView Item that I clicked originally by requesting the parameter values from the remote server.
I am currently doing this up updating the entire ListView by clearing it and rebuilding it.
How do I reference the ListView Item so that I can update the data for that item only?
Thanks,
Jason

Just set the data for your adapter and call notifyDatasetChanged. Android only draws the rows that are visible anyway, so it's pretty efficient.

Knowing the position of the view, this can be done.
View singleItemView = myListView.getChildAt(position);
ImageView icn = (ImageView) singleItemView.findViewById(R.id.icn_icon);
ProgressBar prg = (ProgressBar) singleItemView.findViewById(R.id.prg_icon);
icn.setVisibility(View.GONE);
prg.setVisibility(View.VISIBLE);
(EDIT)
This doesn't work because the "position" of the View could be changed upon returning from another Activity. After the onResume() fires, getView() is called and the position of the visible ListView Items are numbered starting with 0. So, the ListView items (id and position) become renumbered based on visiblity. As a result, I end up accessing the wrong object.

Related

How to check if item in RecyclerView Adapter is still visible after async callback

I want to update one item calling asynchronous call to server API inside onBindViewHolder. I send item at position + position into the callback. Response call arrives in 20 seconds into callback funcion. Into the callback function is returned response and position. Then I call notifyItemChanged(pos, response). And inside payload onBindViewHolder I update item on that position and its View. Problem is that if async request takes 20 seconds and user will scroll quickly throught RecyclerView it will update wrong item View because that view at position could be unbound or could be bound to other item from list.
Is there any way how to track which item at which position is unbound to cancel request? I have to update this one info after adapter is created, because if I will do that before, user will not see any recyclerView item for almost 2 minutes till my list is ready. (only this one call is taking so long).
I wouldn't pass the position as context. I would pass an identifier. Could be an internal integer as id or something. Then you can easily determine which id's are currently visible on the screen and see if that list contains the id of the calback.
I am not sure about your question, but you could work onto your items directly in your adapter.
Then you do:
Adapter adapter = new BaseAdapter(newDataset);
recyclerView.setAdapter(adapter);
recyclerView.notifyDataSetChanged();
Otherwise, if your really work on views rather than dataset, you can do this:
in your adapter:
create a View array
create a custom function View getViewAtPos(int pos)
check if your view is visible in your current scrollview (here)

ListView disappears before updating itself when I pull to refresh

I use a ListView with a PullToRefresh mechanism using SwipeRefreshLayout. I add the SwipeRefreshLayout dynamically in code to the ListView when I initialize.
SwipeRefreshLayout swipeRefreshLayout = new SwipeRefreshLayout(listView.getContext());
if (listView.getParent() != null) {
final ViewGroup parent = (ViewGroup) listView.getParent();
final int index = parent.indexOfChild(listView);
parent.removeViewAt(index);
parent.addView(swipeRefreshLayout, index);
listView.setVisibility(View.VISIBLE);
}
swipeRefreshLayout.addView(listView);
swipeRefreshLayout.setOnRefreshListener(...) { }
The above code adds the swipeRefreshLayout to the parent (at the position that the listView is currently in), and then adds the listView as the child of the swipeRefreshLayout.
When I pull to refresh, a network call is made - data is fetched, stored in the DB, and loaded using a CursorAdapter.
The problem :
When I pull to refresh, I see a blank screen for a second and the UI updates itself with all the items. But when the blank screen is showing and I touch the screen, it responds to click events and the ListView immediately shows.
I need the ListView to display all the time while data is being fetched (while the PTR view is showing) and update immediately when new data is available.
Is there something I'm doing wrong? I have tried running setRefreshing to true by posting a runnable to the SwipeRefreshLayout and fetching new data. I don't think this has got anything to do with the data fetch in particular.
The adapter is not being changed while the blank screen appears (which means that the ListView should still be visible).
Any ideas?
You're removing the view then re-adding it. The adapter should take care of redrawing the new data. Don't remove the view, instead when you refresh the data and its ready, call notifyDataSetChanged() on your adapter.

Is there a way to jump to a specific item in a listview

I am in the process of developing a lengthy list view that is created from a JSON array coming from my server. When an item is selected it could be anywhere in the list and when I return I want to jump back to that specific item.
I was thinking about the setSelection(position) structure but I was curious as to how the position variable is set. Does it need to come from the JSON string or is it a variable that is created while the list view is being filled. If it is created what is the syntax of retrieving it so I can pass it to the Activity in charge of displaying more data and then back to the original Activity when the list view is redisplayed.
As additional information I just added the functionality of storing it in my preferences so it will load faster so it is stored on the phone. If the data has changed due to user interaction I retrieve the new JSON string so maintaining position is not critical.
I was hoping to not need to rebuild my JSON string to contain this variable.
Thanks
use setOnItemClickListener on ListView and save the current position on a local variable (persist or non persist depends on need ) , use this setSelection method on ListView object while you come back (onResume if its a Activity) , check for nulls before setting.
Store your index somewhere and use this to focus on selected item:
// focus on selected item
View v = myListView.getChildAt(index);
int top = (v == null) ? 0 : v.getTop();
myListView.setSelectionFromTop(index, top);

Display item on click on ListView

I need help on a specific task :
I have a ListView in my main activity with a custom Adapter associated, and an OnItemLongClick listener that displays a Dialog with many operations configured (change quantity, cancel item...) and it works like a charm.
My goal is to have a physical copy of the clicked item in the Dialog, to display immediately the changes made.
Since my ListView item is complex and designed by the Adapter, i can't just get the reference to the original object, i need a visual copy of the selected ListView item...
I thought about creating the same structure (ListView and Adapter) with only the selected item associated but it's kind of heavy...
Is there a simpler solution that can help me in this situation ? I mean real copy of the original ListView Item with changes made in my Dialog done to the original object...
Posting your relavent code may help us to guide you more clearly.
However you can get your object in onItemLongClick((AdapterView, View, int position, long) using position params i.e
YourObject objReference = yourActivityClassObjectList.get(position);
now when showing dialog, pass this objReference to your dialog and when changes made, change the contents of this objReference and call
adapter.notifyDataSetChanged();
instead of passing the objReference to dialog, you can pass int position and while changes made, get the reference to that object, change contents and notify data set changed to Adapter.
When you click on one listview item the onListItemClick callback should be fired. As you see in the doc the third parameter is position. You can call YourAdapter.getItem(int) to retrive the element hold by the listview at position

how to access ListView with CheckedTextView?

I'm now developing an application that uses a ListView with a
CheckedTextView on every item that managed by an ArrayAdapter to
support multiple chooses. The contents in my ListView are dynamic, that
means, can be changed during runtime. Now I try to use
ListView.getCheckedItemPositions() to get all checked items, Because I want
to save all the checked positions and auto-check them when user go back to
this page again. So I need to save checked results for every page.
For the first page everything works fine as expected. But when user goes to
another page and make some chooses, the result array that ListView returned
contains some positions that are never checked. I don't why ListView has
this strange behavior. Even for a page that in fact no checked happens but
ListView gives me a result that indicates there's one item has been checked.
could anyone who can teach me how to get the position of CheckedTextView
in its OnClickListener callback?
example code is appreciate.
Thanks in advance...
The listview recycles its views so when you go to a different page and then return to the previous page, the listview recalls the getView() function for its views. To make sure that the order of the checked views are not mixed up, create an arraylist that contains the check state of all the views before initializing the adapter. Then pass the arraylist as an argument for the adapter's constructor. There, in the getView() function, set the checked state of each checkable textview based on the arraylist. Then, return to the activity class and override the onItemClick() event. Using the view that is given to you when the function is called, do the following to get the checkable textview and set its checked state:
listView1.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View selectedView, int position , long id)
{
CheckedTextView tv = (CheckedTextView)selectedView.findViewById(R.id.textview);
if (tv.isChecked())
{
tv.setChecked(false);
checkStatesOfViews.get(position) = false;
}
else
{
tv.setChecked(true);
checkStatesOfViews.get(position) = true;
}
}
});

Categories

Resources