Xamarin Android桌面Widget尺寸适配异常、交互时随机变色问题求助
问题1:尺寸适配问题
- 布局优化:放弃固定宽高的写法,使用权重实现7个TextView等分宽度,适配不同设备的Widget尺寸,修改
list_row.xml如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/d1" android:layout_width="0dp" android:layout_weight="1" android:layout_height="29dp" android:minHeight="29dp" android:textAlignment="center" android:background="@android:color/background_light"/> <!-- 剩余d2到d7的TextView均和d1做相同修改即可 --> </LinearLayout>
- 外层布局适配:将
widget_layout.xml中的LinearLayout和ListView的宽高都改为match_parent,保证控件填充Widget可用空间:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@android:color/white"> <ListView android:id="@+id/listViewWidget" android:choiceMode="none" android:clickable="false" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
- Widget配置调整:修改
widgetinfo.xml的resizeMode为horizontal|vertical,支持横竖方向缩放,可根据需求调整minWidth/minHeight为合理值,避免Widget被缩放到过小。
问题2:颜色异常变化问题
根因分析
该问题是RemoteViews复用机制导致的:Android系统会复用已创建的RemoteViews实例提升性能,你的FillList方法仅对满足条件的TextView设置了背景和文字颜色,未覆盖普通无标记当月日期的样式重置逻辑,未赋值的样式会沿用上一个被复用View的属性,因此会出现随机变色的情况。同时你的OnDataSetChanged方法为空,Widget尺寸调整、系统触发刷新时不会重新加载数据,也会加重显示异常的概率。
修复方案
- 补充
FillList方法的默认样式分支,所有情况都明确赋值样式:
private void FillList(RemoteViews remoteView, int i, int j) { int res = 0; switch(j) { case 0: res = Resource.Id.d1; break; case 1: res = Resource.Id.d2; break; case 2: res = Resource.Id.d3; break; case 3: res = Resource.Id.d4; break; case 4: res = Resource.Id.d5; break; case 5: res = Resource.Id.d6; break; case 6: res = Resource.Id.d7; break; } remoteView.SetTextViewText(res, listItemList[i].days[j]); // 先设置默认样式,再根据条件覆盖 if ((i == 0 && int.Parse(listItemList[i].days[j]) > 7) || (i > 3 && int.Parse(listItemList[i].days[j]) < 15)) { remoteView.SetInt(res, "setBackgroundColor", Android.Graphics.Color.Gray); remoteView.SetTextColor(res, Android.Graphics.Color.White); } else if (listItemList[i].specs[j].Equals("1")) { remoteView.SetInt(res, "setBackgroundColor", Android.Graphics.Color.ParseColor(Preferences.Get("dayColor", "#bf3737"))); remoteView.SetTextColor(res, Android.Graphics.Color.White); } else if (listItemList[i].specs[j].Equals("2")) { remoteView.SetInt(res, "setBackgroundColor", Android.Graphics.Color.ParseColor(Preferences.Get("nightColor", "#203080"))); remoteView.SetTextColor(res, Android.Graphics.Color.White); } else if (new[]{"8","7","4"}.Contains(listItemList[i].specs[j])) { remoteView.SetInt(res, "setBackgroundColor", Android.Graphics.Color.ParseColor(Preferences.Get("specColor", "#2f8254"))); remoteView.SetTextColor(res, Android.Graphics.Color.White); } else if (listItemList[i].specs[j].Equals("О")) { remoteView.SetInt(res, "setBackgroundColor", Android.Graphics.Color.ParseColor(Preferences.Get("vacColor", "#FFE4C4"))); remoteView.SetTextColor(res, Android.Graphics.Color.White); } // 补充普通日期的默认样式 else { remoteView.SetInt(res, "setBackgroundColor", Android.Graphics.Color.White); remoteView.SetTextColor(res, Android.Graphics.Color.Black); } }
- 实现
OnDataSetChanged方法,触发刷新时重新加载数据:
public void OnDataSetChanged() { listItemList.Clear(); works = LoadFromFile(); k = DateTime.DaysInMonth(DateTime.Today.Year, DateTime.Today.Month); i = 0; dt = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1); d = (int)dt.DayOfWeek; if (d == 0) d = 7; populateListItem(); }
- 如果需要响应Widget点击事件,可在
updateWidgetListView方法中给根布局设置PendingIntent,避免系统默认触摸反馈干扰显示。
内容的提问来源于stack exchange,提问作者AlSeed
相关产品推荐
相关产品推荐

