Reputation: 1250
I want to update the layout of some items a in a ListView
in an android app widget if a trigger is given. So I implemented below in getView()
method in RemoteViewsService.RemoteViewsFactory
.
public RemoteViews getViewAt(int position) {
...
int remoteViewId;
if (some condition) {
remoteViewId = R.layout.highlighted_item;
} else {
remoteViewId = R.layout.item;
}
RemoteViews rv = new RemoteViews(mContext.getPackageName(), remoteViewId);
This code works when the widget is loaded for the first time, but when updated using notifyAppWidgetViewDataChanged
the layout persists and is not changed. How can I update xml layout used for a ListView item?
Upvotes: 1
Views: 923
Reputation: 1361
If my assumption is right and you are trying to highlight a list item by changing the background color or something similar I´d suggest to use a selector drawable instead of changing the layout programmatically:
drawable/list_item_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
android:drawable="@drawable/list_item_background_activated" />
<item
android:state_pressed="true"
android:drawable="@drawable/list_item_background_pressed" />
<item
android:drawable="@drawable/list_item_background" />
</selector>
drawable/list_item_background.xml
drawable/list_item_background_pressed.xml
drawable/list_item_background_activated.xml
Define such a drawable for each state in the selector and replace the 'color' with an appropriate color resource.
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="color" />
<stroke
android:width="1dp"
android:color="color" />
</shape>
Apply the list selector to the ListView in the widget´s layout:
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:listSelector="@drawable/list_item_selector" />
I use this for my own widget and it works perfectly. For further information on state lists see this link.
In order to change the entire layout try the following:
public class WidgetListProvider implements RemoteViewsFactory {
private boolean alternateLayout = 1;
@Override
public void onDataSetChanged() {
alternateLayout = alternateLayout == 1 ? 2 : 1;
}
@Override
public RemoteViews getViewAt(int position) {
final RemoteViews rv = new RemoteViews(_context.getPackageName(),
alternateLayout == 1 ? R.layout.list_row : R.layout.list_row2);
[...]
return rv;
}
@Override
public int getViewTypeCount() {
return 2;
}
[...]
}
Important: Note getViewTypeCount() - Because you use two different layouts, you have to return 2 here. If you return 1, a loading view will be displayed for the second layout.
Upvotes: 5