带有 ListView 自定义项的 Android 小部件
Posted
技术标签:
【中文标题】带有 ListView 自定义项的 Android 小部件【英文标题】:Android Widget with ListView Custom Items 【发布时间】:2017-06-09 00:36:58 【问题描述】:我想为我的应用创建一个小部件,显示几行从网络加载的数据。
我有一个包含列表视图、AppWidgetProvider、RemoteViewsService 和 RemoteViewsFactory 的小部件布局。该服务已在清单中注册。
问题是我不能使用自定义的 ListItem 布局。在public RemoteViews getViewAt(int position)
中唯一有效的是使用android.R.layout.simple_list_item_1
,就像在许多基础教程中所做的那样。但是当我尝试使用自己的布局时,我只会为每个条目获得一个“正在加载...”条目(默认加载视图)。
这是我想使用的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_
android:layout_
android:orientation="horizontal"
android:padding="10dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:layout_
android:layout_
android:layout_marginRight="@dimen/cardview_spacing"
android:layout_marginEnd="@dimen/cardview_spacing"
android:layout_gravity="center_horizontal"
android:textSize="@dimen/textTitle"
android:id="@+id/plan_entry_lesson" />
<TextView
android:layout_
android:layout_
android:layout_marginRight="@dimen/cardview_spacing"
android:layout_marginEnd="@dimen/cardview_spacing"
android:layout_gravity="center_horizontal"
android:textSize="@dimen/textTitle"
android:id="@+id/plan_entry_class" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:layout_
android:layout_
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="start"
android:textSize="@dimen/textSmallTitle"
android:id="@+id/plan_header"
android:text="@string/plan_header"/>
<TextView
android:layout_
android:layout_
android:layout_marginStart="@dimen/cardview_spacing"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="start"
android:id="@+id/plan"
android:layout_marginLeft="@dimen/cardview_spacing" />
<TextView
android:layout_
android:layout_
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="start"
android:textSize="@dimen/textSmallTitle"
android:id="@+id/subst_header"
android:text="@string/subst_header"/>
<TextView
android:layout_
android:layout_
android:layout_marginStart="@dimen/cardview_spacing"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="start"
android:id="@+id/subst"
android:layout_marginLeft="@dimen/cardview_spacing" />
<TextView
android:layout_
android:layout_
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="start"
android:textSize="@dimen/textSmallTitle"
android:id="@+id/comment_header"
android:text="@string/comment_header"/>
<TextView
android:layout_
android:layout_
android:layout_marginStart="@dimen/cardview_spacing"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="start"
android:id="@+id/comment"
android:layout_marginLeft="@dimen/cardview_spacing" />
</LinearLayout>
</LinearLayout>
由于数据是异步加载的,我建议数据根本不存在或类似的东西,但我的调试输出显示数据可用并且我创建的视图不为空。但是,我只能使用 android 示例列表项。
对此有何建议?
我的 getViewTypeCount() 目前返回 1!(不是 0,这似乎是一个常见问题)
为了完整性:RemoteViewsFactory:
public class WidgetDataProvider implements RemoteViewsService.RemoteViewsFactory
private static final String TAG = "WidgetDataProvider";
private Vplan plan;
private List<VplanEntry> mCollection = new ArrayList<>();
private Context mContext = null;
public WidgetDataProvider(Context context, Intent intent)
mContext = context;
plan = new Vplan(mContext, "today");
@Override
public void onCreate()
initData();
@Override
public void onDataSetChanged()
initData();
@Override
public void onDestroy()
@Override
public int getCount()
return mCollection.size();
@Override
public RemoteViews getViewAt(int position)
Log.d("WIDGET", "getViewAt " + position);
VplanEntry entry = mCollection.get(position);
Log.d("WIDGET", "entry plan: " + entry.getPlan());
RemoteViews view = new RemoteViews(mContext.getPackageName(),
android.R.layout.simple_list_item_1);
String text = entry.getCls() + " " + entry.getLesson() + ":\n"
+ entry.getPlan() +"\n"
+ entry.getSubstitution() + "\n"
+ entry.getComment();
view.setTextViewText(android.R.id.text1, text);
//view.setTextViewText(R.id.plan_entry_lesson, entry.getLesson());
return view;
@Override
public RemoteViews getLoadingView()
//return new RemoteViews(mContext.getPackageName(),
// R.layout.vplan_appwidget_loading);
return null;
@Override
public int getViewTypeCount()
return 1;
@Override
public long getItemId(int position)
return position;
@Override
public boolean hasStableIds()
return true;
private void initData()
mCollection.clear();
if (plan.isLoaded() && plan.upToDate())
mCollection.clear();
Log.d("WIDGET", "Data present");
for (VplanEntry entry : plan.getEntries())
mCollection.add(entry);
Log.d("WIDGET", "Entries: " + mCollection.size());
AppWidgetManager awm = AppWidgetManager.getInstance(mContext);
awm.notifyAppWidgetViewDataChanged(awm.getAppWidgetIds(new ComponentName(mContext, WidgetService.class)), R.id.widgetListView);
else
Log.d("WIDGET", "Loading started");
plan.load(new SuccessCallback()
@Override
public void callback(boolean success)
Log.d("WIDGET", "Loading finished: " + success);
if (success)
initData();
);
【问题讨论】:
【参考方案1】:问题是我的布局的宽度高于所需的最小 Widget 宽度...
改变宽度解决了这个问题。
【讨论】:
以上是关于带有 ListView 自定义项的 Android 小部件的主要内容,如果未能解决你的问题,请参考以下文章
将图像按钮添加到 ListView 中的自定义项的布局会停止接收长按事件