- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
更新:I created a repository使用更少的代码使其更容易理解。
我正在尝试创建一个小部件。我像这里描述的那样做了:https://stackoverflow.com/a/6093753/2180161
它部分起作用,但我有一个非常奇怪的错误。我制作了一个截屏视频,这样更容易理解我的意思: http://c.maysi.de/c6H9
如您所见,有些项目是随机添加的。 (添加到另一个 RemoteViews
对象的 RemoteViews
)当我调整小部件大小时也会发生同样的情况。
我在日志中打印出来的东西和预期的一样。没有错误的数据。滚动时也没有新的日志条目。
这是我的代码:
远程 View 工厂:
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MyWidgetViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private static ArrayList<Item> items = new ArrayList<>();
private static int itemnr = 0;
private static int subitemnr = 0;
private int appWidgetId;
private Context context;
public MyWidgetViewsFactory(Context context, Intent intent) {
this.context = context;
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
//Some random data to display
for (int i = 0; i < 10; i++) {
Item item = new Item(String.valueOf(itemnr++));
for (int j = 0; j < 3; j++) {
String[] subitem = {String.valueOf(subitemnr++), String.valueOf(subitemnr++), String.valueOf(subitemnr++)};
item.addSubitem(subitem);
}
items.add(item);
}
}
@Override
public void onCreate() {
// no-op
}
@Override
public void onDestroy() {
// no-op
}
@Override
public int getCount() {
return items.size();
}
@Override
public RemoteViews getViewAt(int position) {
Log.d("MyWidgetViewsFactory", "getViewAt(" + position + "):" + items.get(position));
Item item = items.get(position);
RemoteViews itemView = new RemoteViews(context.getPackageName(), R.layout.widget_listview_item);
itemView.setTextViewText(R.id.textView_itemnr, item.getItemNr());
for (String[] s : item.getSubitems()) {
Log.d("MyWidgetViewsFactory", "subitem:" + s[0] + "|" + s[1] + "|" + s[2]);
RemoteViews subitem = new RemoteViews(context.getPackageName(), R.layout.widget_listview_subitem);
subitem.setTextViewText(R.id.textView_1, s[0]);
subitem.setTextViewText(R.id.textView_2, s[1]);
subitem.setTextViewText(R.id.textView_3, s[2]);
itemView.addView(R.id.linearLayout_item_body, subitem);
}
return itemView;
}
@Override
public RemoteViews getLoadingView() {
return (null);
}
@Override
public int getViewTypeCount() {
return (1);
}
@Override
public long getItemId(int position) {
return (position);
}
@Override
public boolean hasStableIds() {
return (true);
}
@Override
public void onDataSetChanged() {
// no-op
}
class Item {
private ArrayList<String[]> subitems = new ArrayList<>();
private String itemnr = "";
Item(String itemnr) {
this.itemnr = itemnr;
}
Item() {
}
public void addSubitem(String[] subitem) {
this.subitems.add(subitem);
}
public ArrayList<String[]> getSubitems() {
return subitems;
}
public String getItemNr() {
return itemnr;
}
public void setItemNr(String itemnr) {
this.itemnr = itemnr;
}
}
}
AppWidgetProvider
public class MyWidgetProvider extends AppWidgetProvider {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
Log.d("MyWidgetProvider", "appWidgetIds.lenght:" + appWidgetIds.length);
for (int appWidgetId : appWidgetIds) {
Intent svcIntent = new Intent(context, MyWidgetService.class);
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.widget_root);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
widget.setRemoteAdapter(R.id.listView_widget, svcIntent);
else
widget.setRemoteAdapter(appWidgetId, R.id.listView_widget, svcIntent);
/*
Intent clickIntent = new Intent(context, MainActivity.class);
PendingIntent clickPI = PendingIntent.getActivity(context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
widget.setPendingIntentTemplate(R.id.listView_widget, clickPI);*/
appWidgetManager.updateAppWidget(appWidgetId, widget);
}
}
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}
RemoteViewsService
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class MyWidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return (new MyWidgetViewsFactory(this.getApplicationContext(), intent));
}
}
所有其他资源 can you find in the repo at GitHub.
Logcat 输出:
08-08 02:11:10.858 32427-32444/? D/MyWidgetViewsFactory﹕ getViewAt(0):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@3e7179c9
08-08 02:11:10.860 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:0|1|2
08-08 02:11:10.864 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:3|4|5
08-08 02:11:10.866 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:6|7|8
08-08 02:11:10.927 32427-32443/? D/MyWidgetViewsFactory﹕ getViewAt(0):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@3e7179c9
08-08 02:11:10.927 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:0|1|2
08-08 02:11:10.927 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:3|4|5
08-08 02:11:10.927 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:6|7|8
08-08 02:11:10.931 32427-32443/? D/MyWidgetViewsFactory﹕ getViewAt(1):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@23e248ce
08-08 02:11:10.931 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:9|10|11
08-08 02:11:10.931 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:12|13|14
08-08 02:11:10.931 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:15|16|17
08-08 02:11:10.933 32427-32443/? D/MyWidgetViewsFactory﹕ getViewAt(2):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@16dbf3ef
08-08 02:11:10.933 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:18|19|20
08-08 02:11:10.933 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:21|22|23
08-08 02:11:10.933 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:24|25|26
08-08 02:11:10.936 32427-32443/? D/MyWidgetViewsFactory﹕ getViewAt(3):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@19d3defc
08-08 02:11:10.936 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:27|28|29
08-08 02:11:10.936 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:30|31|32
08-08 02:11:10.936 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:33|34|35
08-08 02:11:10.938 32427-32443/? D/MyWidgetViewsFactory﹕ getViewAt(4):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@ee985
08-08 02:11:10.938 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:36|37|38
08-08 02:11:10.938 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:39|40|41
08-08 02:11:10.938 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:42|43|44
08-08 02:11:10.941 32427-32443/? D/MyWidgetViewsFactory﹕ getViewAt(8):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@335e23da
08-08 02:11:10.941 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:72|73|74
08-08 02:11:10.941 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:75|76|77
08-08 02:11:10.941 32427-32443/? D/MyWidgetViewsFactory﹕ subitem:78|79|80
08-08 02:11:10.943 32427-32447/? D/MyWidgetViewsFactory﹕ getViewAt(9):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@229de00b
08-08 02:11:10.943 32427-32447/? D/MyWidgetViewsFactory﹕ subitem:81|82|83
08-08 02:11:10.943 32427-32447/? D/MyWidgetViewsFactory﹕ subitem:84|85|86
08-08 02:11:10.943 32427-32447/? D/MyWidgetViewsFactory﹕ subitem:87|88|89
08-08 02:11:10.945 32427-32444/? D/MyWidgetViewsFactory﹕ getViewAt(5):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@2afdeee8
08-08 02:11:10.945 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:45|46|47
08-08 02:11:10.945 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:48|49|50
08-08 02:11:10.945 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:51|52|53
08-08 02:11:10.948 32427-32444/? D/MyWidgetViewsFactory﹕ getViewAt(7):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@1c599901
08-08 02:11:10.948 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:63|64|65
08-08 02:11:10.948 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:66|67|68
08-08 02:11:10.948 32427-32444/? D/MyWidgetViewsFactory﹕ subitem:69|70|71
08-08 02:11:10.951 32427-32447/? D/MyWidgetViewsFactory﹕ getViewAt(6):de.mayerhofersimon.listviewproblem.MyWidgetViewsFactory$Item@368aa3a6
08-08 02:11:10.951 32427-32447/? D/MyWidgetViewsFactory﹕ subitem:54|55|56
08-08 02:11:10.951 32427-32447/? D/MyWidgetViewsFactory﹕ subitem:57|58|59
08-08 02:11:10.951 32427-32447/? D/MyWidgetViewsFactory﹕ subitem:60|61|62
因此数据得到正确传递。它只是没有得到正确显示...
顺便说一句:它应该是这样的:http://c.maysi.de/cB8K
难道问题出在嵌套的远程 View 上?因为所有外部远程 View 都显示正确...
最佳答案
您对 ListView 回收问题的想法是正确的。您需要了解底层的运作方式。
MVC 模式
The Android graphics works on the MVC pattern i.e. Model-View and Controller pattern. Model is your data, database in your case, View is your layout or graphical portion,such as ListView or RecyclerView or RemoteView. Controller changes your view after data update, parent View or ViewGroup in your case the
RemoteViewsService.RemoteViewsFactory
is the controller. I suggest to read further by googling the MVC model.
Pattern是如何实现的?
任何时候数据改变, View 应该由 Controller 更新。 Android 框架让您有机会通过覆盖 getViewAt(int position)
在给定位置显示您的 View 和您的数据。 Controller 调用 getViewAt(int position)
来获取 ListView 或 RecyclerView 中给定位置的 View 。 ListView 或 RecyclerView 仅呈现屏幕上可见的行。例如,如果您在 ListView 中有 100 个项目并且只有 7 个在屏幕上可见,那么它将调用 getItemAt(int) 7 次。每次滚动时,都会为可见行调用 getItemAt(int)。 ListView 和 RemoteView 可以自由回收/重用之前通过 getItemAt(int position) 返回的 View 。它确保应用程序的图形部分消耗的内存是有限的
为什么会有奇怪的行为?
首先,屏幕上所有可见的东西都是一个View
,例如TextView、ImageView和ListView等。如果不是,它就不能显示在屏幕上。 RemoteView不是 View 。您传递要使用 RemoteView( View + 数据)显示的布局和数据。
此处我指的是您的截屏视频以进行解释。
1) Initialization: The
ListView
in your case, initially creates say 6 rows based on the visible space on screen andgetViewAt(int position)
is called once ifgetCount()
returns 1. I request to check the return value of the getCount() of the List adapter.
2) You scrolled down: Nothing happens to theListView
and rendering of new Rows.
3) You Scrolled Up: getPositionAt(int position) is called again and RemoteView is passed back.Two rows are visible now. I request to check the getCount() return value. It should be 2 if not than the reason could be caching of rows by ListView.
4) You scrolled down: Nothing happens to theListView
and rendering of new Rows.
5) You Scrolled Up: Refer 3. The getCount() should be 3 and so on.
你应该做什么?
根据您的实现,您只创建了一次 RemoteView 并尝试在 getItemAt(int)
中重复使用相同的 View ,可能是为了节省布局膨胀时间。
要解决此问题,您必须在每次调用 getItemAt(int)
时提供FRESH RemoteView
。
@Override
public RemoteViews getViewAt(int position)
{
Log.d("VplanWidgetViewsFactory", "getViewAt("+position+"):"+stunden.get(position));
//TODO: Store context when constructor is called.
RemoteView rv = new RemoteViews(context.getPackageName(), R.layout.fragment_stunde_widget);
rv.setTextViewText(R.id.textView_lesson_nr, "" + (position + 1) + "."); <= I have not tested this.
return rv;
//return stunden.get(position); <=COMMENT THIS
}
关于android - 小部件中的 ListView 在滚动和调整大小时随机添加项目(嵌套远程 View ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31713373/
我让随机数低于之前的随机数。 if Airplane==1: while icounter0: print "You have enoph fuel to get to New
是否可以生成 BigFloat 的随机数?类型均匀分布在区间 [0,1)? 我的意思是,因为 rand(BigFloat)不可用,看来我们必须使用 BigFloat(rand())为了那个结局。然而,
我正在尝试学习 Kotlin,所以我正在学习互联网上的教程,其中讲师编写了一个与他们配合良好的代码,但它给我带来了错误。 这是错误 Error:(26, 17) Kotlin: Cannot crea
是否有任何方法可以模拟 Collections.shuffle 的行为,而不使比较器容易受到排序算法实现的影响,从而保证结果的安全? 我的意思是不违反类似的契约(Contract)等.. 最佳答案 在
我正在创建一个游戏,目前必须处理一些math.random问题。 我的Lua能力不是那么强,你觉得怎么样 您能制定一个使用 math.random 和给定百分比的算法吗? 我的意思是这样的函数: fu
我想以某种方式让按钮在按下按钮时随机改变位置。我有一个想法如何解决这个问题,其中一个我在下面突出显示,但我已经认为这不是我需要的。 import javafx.application.Applicat
对于我的 Java 类(class),我应该制作一个随机猜数字游戏。我一直陷入过去几天创建的循环中。程序的输出总是无限循环,我不明白为什么。非常感谢任何帮助。 /* This program wi
我已经查看了涉及该主题的一些其他问题,但我没有在任何地方看到这个特定问题。我有一个点击 Web 元素的测试。我尝试通过 ID 和 XPath 引用它,并使用 wait.until() 等待它变得可见。
我在具有自定义类的字典和列表中遇到了该异常。示例: List dsa = (List)Session["Display"]; 当我使用 Session 时,转换工作了 10-20 次..然后它开始抛
需要帮助以了解如何执行以下操作: 每隔 2 秒,这两个数字将生成包含从 1 到 3 的整数值的随机数。 按下“匹配”按钮后,如果两个数字相同,则绿色标签上的数字增加 1。 按下“匹配”按钮后,如果两个
void getS(char *fileName){ FILE *src; if((src = fopen(fileName, "r")) == NULL){ prin
如果我有 2 个具有以下字段的 MySQL 数据库... RequestDB: - Username - Category DisplayDB: - Username - Category
我有以下语句 select random() * 999 + 111 from generate_series(1,10) 结果是: 690,046183290426 983,732229881454
我有一个使用 3x4 CSS 网格构建的简单网站。但出于某种原因,当我在 chrome“检查”中检查页面时,有一个奇怪的空白 显然不在我的代码中的标签。 它会导致网站上出现额外的一行,从而导致出现
我有两个动画,一个是“过渡”,它在悬停时缩小图像,另一个是 animation2,其中图像的不透明度以周期性间隔重复变化。 我有 animation2 在图像上进行,当我将鼠标悬停在它上面时,anim
如图所示post在 C++ 中有几种生成随机 float 的方法。但是我不完全理解答案的第三个选项: float r3 = LO + static_cast (rand()) /( static_c
我正在尝试将类添加到具有相同类的三个 div,但我不希望任何被添加的类重复。 我有一个脚本可以将一个类添加到同时显示的 1、2 或 3 个 div。期望的效果是将图像显示为背景图像,并且在我的样式表中
我有一个基本上可以工作的程序,它创建由用户设置的大小的嵌套列表,并根据用户输入重复。 但是,我希望各个集合仅包含唯一值,目前这是我的输出。 > python3 testv.py Size of you
我正在尝试基于 C# 中的种子生成一个数字。唯一的问题是种子太大而不能成为 int32。有什么方法可以像种子一样使用 long 吗? 是的,种子必须很长。 最佳答案 这是我移植的 Java.Util.
我写这个函数是为了得到一个介于 0 .. 1 之间的伪随机 float : float randomFloat() { float r = (float)rand()/(float)RAN
我是一名优秀的程序员,十分优秀!