How to Dynamically Update a Listview on Android

update listview dynamically with adapter

Use a ArrayAdapter backed by an ArrayList. To change the data, just update the data in the list and call adapter.notifyDataSetChanged().

Android - Dynamically Updating a custom ListView after items in an ArrayList are added

Your adapter does not get the new data, because you are initializing it with its own set of data.

One possibility would be to instantiate a new adapter and assign it to the ListView.

Add a field for your ListView in your activity:

public TextView tv;
private int variantPosition;
CustomListAdapter customListAdapter;
CurrentOrderClass currentOrder = new CurrentOrderClass();
ListView myListView; //Listview here

In onCreate, set myListView to point to your ListView:

final ListView lv1 = (ListView) findViewById(R.id.listViewProductOrder)
myListView = lv1;

Finally, when you change your data, create a new Adapter for the new data:

myListView.setAdapter(new CustomListAdapter(this, getListData());

Alternatively, modify your Custom adapter to contain a setListData method:

public class CustomListAdapter extends BaseAdapter {

private ArrayList<CurrentOrderClass> listData;

private LayoutInflater layoutInflater;

public CustomListAdapter(Context context, ArrayList<CurrentOrderClass> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
}

public void setListData(ArrayList<CurrentOrderClass> data){
listData = data;
}

@Override
public int getCount() {
return listData.size();
}


@Override
public Object getItem(int position) {
return listData.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.variantView = (TextView) convertView.findViewById(R.id.variant);
holder.unitView = (TextView) convertView.findViewById(R.id.unit);
holder.quantityView = (TextView) convertView.findViewById(R.id.quantity);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}

holder.variantView.setText(listData.get(position).getVariantArray().get(position).toString());
holder.unitView.setText(listData.get(position).getUnitArray().get(position).toString());
holder.quantityView.setText(String.valueOf(listData.get(position).getQuantityRow()));

return convertView;
}

static class ViewHolder {
TextView variantView;
TextView unitView;
TextView quantityView;
}


}

Then, after modifying your data, just call:

customListAdapter.setListData(getListData());
customListAdapter.notifyDataSetChanged();

Android How to dynamically update a listview?

Take a look at the answer to this question for an explanation / example of how to maintain scroll position after adding items to a list: Retaining position in ListView after calling notifyDataSetChanged

Basically, you make a note of the position and scroll offset of the first visible item in the list before adding new data. Then afterwards, you restore the previous position and scroll offset.

However, because you're adding new items at the top of the list, the position returned by getFirstVisiblePosition() may refer to a different item after refreshing. The item that was at position 0 before refreshing may now be position 10. To fix that, you need to determine the number of new items returned by timeline.php and add it to index, like this:

mList.setSelectionFromTop(index + newItemCount, top);

You could probably determine which items are new by comparing the date field.

(By the way, if timeline.php only returns the most recent set of items, you could run into trouble if the user has scrolled to an older item which is no longer returned by timeline.php. After setting the new data, the old item will no longer be present, so you won't be able to scroll to it.

To fix that, you could keep the old ArrayList around and only add new items to it in doInBackground(). And call notifyDataSetChanged() in doInBackground(). That way, the adapter will still have access to older items.)

How to dynamically update a ListView on Android

First, you need to create an XML layout that has both an EditText, and a ListView.

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<!-- Pretty hint text, and maxLines -->
<EditText android:id="@+building_list/search_box"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="type to filter"
android:inputType="text"
android:maxLines="1"/>

<!-- Set height to 0, and let the weight param expand it -->
<!-- Note the use of the default ID! This lets us use a
ListActivity still! -->
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>

</LinearLayout>

This will lay everything out properly, with a nice EditText above the ListView. Next, create a ListActivity as you would normally, but add a setContentView() call in the onCreate() method so we use our recently declared layout. Remember that we ID'ed the ListView specially, with android:id="@android:id/list". This allows the ListActivity to know which ListView we want to use in our declared layout.

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.filterable_listview);

setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList());
}

Running the app now should show your previous ListView, with a nice box above. In order to make that box do something, we need to take the input from it, and make that input filter the list. While a lot of people have tried to do this manually, most ListView Adapter classes come with a Filter object that can be used to perform the filtering automagically. We just need to pipe the input from the EditText into the Filter. Turns out that is pretty easy. To run a quick test, add this line to your onCreate() call

adapter.getFilter().filter(s);

Notice that you will need to save your ListAdapter to a variable to make this work - I have saved my ArrayAdapter<String> from earlier into a variable called 'adapter'.

Next step is to get the input from the EditText. This actually takes a bit of thought. You could add an OnKeyListener() to your EditText. However, this listener only receives some key events. For example, if a user enters 'wyw', the predictive text will likely recommend 'eye'. Until the user chooses either 'wyw' or 'eye', your OnKeyListener will not receive a key event. Some may prefer this solution, but I found it frustrating. I wanted every key event, so I had the choice of filtering or not filtering. The solution is a TextWatcher. Simply create and add a TextWatcher to the EditText, and pass the ListAdapter Filter a filter request every time the text changes. Remember to remove the TextWatcher in OnDestroy()! Here is the final solution:

private EditText filterText = null;
ArrayAdapter<String> adapter = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.filterable_listview);

filterText = (EditText) findViewById(R.id.search_box);
filterText.addTextChangedListener(filterTextWatcher);

setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
getStringArrayList());
}

private TextWatcher filterTextWatcher = new TextWatcher() {

public void afterTextChanged(Editable s) {
}

public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}

public void onTextChanged(CharSequence s, int start, int before,
int count) {
adapter.getFilter().filter(s);
}

};

@Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
}

How to update Android ListView with dynamic data in real time?

I experimented with ListView, and you essentially have to update the ListView cells manually without calling notifyDataSetChanged() if you have realtime data and you want the ListView to update with better performance.

notifyDataSetChanged() causes the ListView to rebuild its entire View hierarchy is very slow if you are calling it frequently (i.e. once every second).

Note (2014). This DOES NOT APPLY if you are using normal modern ListView with a ViewHolder pattern. You simply call 'notifyDataSetChanged' and that's all there is to it. It is incredibly efficient as Android knows to only update the cells on the screen.

I implemented a scheme where if my data set size changed from one update to the next, I call notifyDataSetChanged(). If the data set size remained constant from one update to the next (such that the number of cells in the ListView is the same as before when a redraw of the data is needed), then I iterate over the ListView.getFirstVisiblePosition() : getLastVisiblePosition(), and update the visible cells only.

How to dynamically change List items for the ListView in Android?

Assuming the number of steps is fairly small, I usually use a LinearLayout here, and add the necessary views.

To do this, you simply need to add a LinearLayout to your item view to contain the steps.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/step_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:textSize="25sp" />

<LinearLayout
android:id="@+id/steps"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>

Then you add steps to your item view via the adapter. Make sure you clear the previous steps in the view (also making sure you use the ViewHolder pattern).

public class StepsAdapter extends ArrayAdapter<FirstAidSteps> {

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (v == null) {
v = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.stepName = (TextView) v.findViewById(R.id.step_heading);
holder.steps = (LinearLayout) v.findViewById(R.id.steps);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}

final FirstAidSteps steps = getItem(position);
holder.stepName.setText(steps.getStepName());

holder.steps.removeAllViews();
for (String step : steps.getSteps()) {
holder.steps.addView(createStepView(step));
}

return v;
}

private static class ViewHolder {
TextView stepName;
LinearLayout steps;
}
}

In this case, createStepView() is an exercise for the reader.

Depending on your layout and possible number of steps, this may not be the best solution for you. If you will potentially have a lot of steps you may want to look into some sort of recycler view, or other recycling container.

How to refresh ListView dynamically?

adapter.notifyDataSetChanged();

You can call the above method to refresh list view any time. In your case call it after you delete a record from database.



Related Topics



Leave a reply



Submit