我正在尝试关注this example以创建WearableListView。我在BoxInsetLayout文件上有问题,因为我在尝试渲染布局时遇到onLayout()错误。这是堆栈跟踪:
java.lang.ClassCastException: com.android.layoutlib.bridge.android.support.Adapter$ViewHolder cannot be cast to android.support.wearable.view.WearableListView$ViewHolder
at android.support.wearable.view.WearableListView.getChildViewHolder(WearableListView.java:521)
at android.support.wearable.view.WearableListView$LayoutManager.notifyChildrenAboutProximity(WearableListView.java:762)
at android.support.wearable.view.WearableListView$LayoutManager.performLayoutChildren(WearableListView.java:883)
at android.support.wearable.view.WearableListView$LayoutManager.onLayoutChildren(WearableListView.java:854)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2118)
at android.support.v7.widget.RecyclerView.onLayout_Original(RecyclerView.java:2415)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.wearable.view.BoxInsetLayout.onLayout_Original(BoxInsetLayout.java:318)
at android.support.wearable.view.BoxInsetLayout.onLayout(BoxInsetLayout.java)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.render(RenderSessionImpl.java:376)
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:428)
at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:350)
at com.android.tools.idea.rendering.RenderTask$2.compute(RenderTask.java:510)
at com.android.tools.idea.rendering.RenderTask$2.compute(RenderTask.java:498)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:888)
at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:498)
at com.android.tools.idea.rendering.RenderTask.access$600(RenderTask.java:72)
at com.android.tools.idea.rendering.RenderTask$3.call(RenderTask.java:610)
at com.android.tools.idea.rendering.RenderTask$3.call(RenderTask.java:607)
at com.android.tools.idea.rendering.RenderService.runRenderAction(RenderService.java:362)
at com.android.tools.idea.rendering.RenderTask.render(RenderTask.java:607)
at com.android.tools.idea.rendering.RenderTask.render(RenderTask.java:629)
at com.intellij.android.designer.designSurface.AndroidDesignerEditorPanel$6.run(AndroidDesignerEditorPanel.java:480)
at com.intellij.util.ui.update.MergingUpdateQueue.execute(MergingUpdateQueue.java:320)
at com.intellij.util.ui.update.MergingUpdateQueue.execute(MergingUpdateQueue.java:310)
at com.intellij.util.ui.update.MergingUpdateQueue$2.run(MergingUpdateQueue.java:254)
at com.intellij.util.ui.update.MergingUpdateQueue.flush(MergingUpdateQueue.java:269)
at com.intellij.util.ui.update.MergingUpdateQueue.flush(MergingUpdateQueue.java:227)
at com.intellij.util.ui.update.MergingUpdateQueue.run(MergingUpdateQueue.java:217)
at com.intellij.util.concurrency.QueueProcessor.runSafely(QueueProcessor.java:238)
at com.intellij.util.Alarm$Request$1.run(Alarm.java:351)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
这是我的xml文件,其中包含WearableListView:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/grey"
android:layout_height="match_parent"
android:layout_width="match_parent">
<FrameLayout
android:id="@+id/frame_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
app:layout_box="left|bottom|right">
<android.support.wearable.view.WearableListView
android:id="@+id/wearable_list"
android:layout_height="match_parent"
android:layout_width="match_parent">
</android.support.wearable.view.WearableListView>
</FrameLayout>
</android.support.wearable.view.BoxInsetLayout>
另外,在我的DevicesListActivity.java上我实现了WearableListView.ClickListener接口,但是当我尝试通过id获取布局时,我得到一个空的WearableListView对象(我认为这是因为我之前说过的错误,但是我'我不确定):
public class DevicesListActivity extends Activity implements WearableListView.ClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_devices_list);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
}
});
WearableListView listView = (WearableListView) findViewById(R.id.wearable_list);
if (listView == null) {
Log.d("DevicesListActivity", "ListView is null");
} else {
listView.setAdapter(new WearableListViewAdapter("Prueba", "00:00", this));
listView.setClickListener(this);
}
}
@Override
public void onClick(WearableListView.ViewHolder viewHolder) {
Toast.makeText(this, "Clic realizado", Toast.LENGTH_LONG);
}
@Override
public void onTopEmptyRegionClick() {
}
}
任何帮助?
提前致谢。
答案 0 :(得分:0)
我不认为您的第二个错误来自onlayout()错误问题,因为我有相同的错误并且我的可穿戴列表视图完美运行。
它可能来自WatchViewStub,因为我尝试了没有它成功,并且让xml包含你的R.id.watch_view_stub会很有用。
希望有所帮助。
我找到了onLayout()问题的解决方案,但我不知道它是否有用:https://code.google.com/p/android/issues/detail?id=186918
创建此类:
public class WearableListViewFixEditor extends WearableListView {
public WearableListViewFixEditor(Context context) {
super(context);
}
public WearableListViewFixEditor(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WearableListViewFixEditor(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* Override this method to implement the choice for the intellij android designer
*/
@Override
public ViewHolder getChildViewHolder(View child) {
if (!isInEditMode()) {
return super.getChildViewHolder(child);
} else {
/**
* Override this with an empty body to avoid an error in intellij android designer
*/
return new WearableListView.ViewHolder(new View(getContext())) {
@Override
protected void onCenterProximity(boolean isCentralItem, boolean animate) {
}
};
}
}
}
之后修改你的xml文件如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@color/grey"
android:layout_height="match_parent"
android:layout_width="match_parent">
<FrameLayout
android:id="@+id/frame_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
app:layout_box="left|bottom|right">
<your.package.path.WearableListViewFixEditor
android:id="@+id/wearable_list"
android:layout_height="match_parent"
android:layout_width="match_parent">
</your.package.path.WearableListViewFixEditor>
</FrameLayout>
</android.support.wearable.view.BoxInsetLayout>
答案 1 :(得分:0)
我设法用this example之后的null WearableListView对象解决了我的问题,但我忘了在之后发布答案。我所做的是将我的WearableListView布局移动到文件 round_activity_devices_list.xml (因为我的设备是圆的,但我认为如果我将我的布局添加到rect_activity_devices_list.xml,这也适用于rect设备) :
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/grey"
tools:context=".DevicesListActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="25dp"
android:textSize="17dp"
android:text="Select a device"
android:id="@+id/listTitle"/>
<android.support.wearable.view.WearableListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/wearable_list"
app:layout_box="all" />
</android.support.wearable.view.BoxInsetLayout>
这些是我现在拥有的java类:
<强> WearableListViewAdapter.java 强>
public class WearableListViewAdapter extends WearableListView.Adapter {
private final String TAG = "WearableListViewAdapter";
private String[] deviceName;
private String deviceAddress = "Not being used.";
private final Context context;
private final LayoutInflater inflater;
public WearableListViewAdapter(Context context, String[] devices) {
// Log.d(TAG, "WearableListViewAdapter constructor accessed.");
this.deviceName = devices;
// this.deviceAddress = device;
this.context = context;
this.inflater = LayoutInflater.from(context);
}
@Override
public void onBindViewHolder(WearableListView.ViewHolder holder, int position) {
ItemViewHolder itemViewHolder = (ItemViewHolder) holder;
TextView deviceNameText = itemViewHolder.deviceNameText;
TextView deviceAddressText = itemViewHolder.deviceAddressText;
deviceNameText.setText(deviceName[position]);
deviceAddressText.setText(deviceAddress);
holder.itemView.setTag(position);
Log.d(TAG, "onBindViewHolder");
}
@Override
public int getItemCount() {
return deviceName.length;
}
@Override
public WearableListView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ItemViewHolder(inflater.inflate(R.layout.list_item, null));
}
public static class ItemViewHolder extends WearableListView.ViewHolder {
private TextView deviceNameText;
private TextView deviceAddressText;
public ItemViewHolder (View itemView) {
super(itemView);
deviceNameText = (TextView) itemView.findViewById(R.id.deviceNameText);
deviceAddressText = (TextView) itemView.findViewById(R.id.deviceAddressText);
}
}
}
<强> WearableListItemLayout.java 强>
public class WearableListItemLayout extends LinearLayout
implements WearableListView.OnCenterProximityListener {
private ImageView deviceImg;
private TextView deviceName;
private TextView deviceAddress;
public WearableListItemLayout(Context context) {
this(context, null);
}
public WearableListItemLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WearableListItemLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// Get references to the icon and text in the item layout definition
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// These are defined in the layout file for list items
// (see next section)
deviceImg = (ImageView) findViewById(R.id.deviceImg);
deviceName = (TextView) findViewById(R.id.deviceNameText);
deviceAddress = (TextView) findViewById(R.id.deviceAddressText);
}
@Override
public void onCenterPosition(boolean animate) {
deviceImg.animate().scaleX(1f).scaleY(1f).alpha(1);
deviceName.animate().scaleX(1f).scaleY(1f).alpha(1);
deviceAddress.animate().scaleX(1f).scaleY(1f).alpha(1);
}
@Override
public void onNonCenterPosition(boolean animate) {
deviceImg.animate().scaleX(0.8f).scaleY(0.8f).alpha(0.6f);
deviceName.animate().scaleX(0.8f).scaleY(0.8f).alpha(0.6f);
deviceAddress.animate().scaleX(1f).scaleY(1f).alpha(1);
}
}
<强> DevicesListActivity.java 强>
public class DevicesListActivity extends Activity implements WearableListView.ClickListener {
private final String TAG = "DevicesListActivity";
private WearableListView listView;
private TextView listTitleText;
private Context context = this;
private Messenger mainActivityMessenger;
private String[] devicesName = { "SensorTag", "BH" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_devices_list);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
listView = (WearableListView) stub.findViewById(R.id.wearable_list);
listTitleText = (TextView) stub.findViewById(R.id.listTitle);
Log.d(TAG, "listView created.");
if (listView == null) {
Log.d("DevicesListActivity", "ListView is null");
} else {
listView.setAdapter(new WearableListViewAdapter(context, devicesName));
listView.setClickListener((WearableListView.ClickListener) context);
mainActivityMessenger = getIntent()
.getParcelableExtra("mainactivitymessenger");
}
}
});
}
...
如您所见,父布局仍然是BoxInsetLayout,但我删除了FrameLayout,因为我暂时不需要它。但是,onLayout()的错误仍然存在,但实际上我不需要修复它,因为我的应用程序正常工作,它似乎只是一个渲染问题。无论如何,如果您认为此修复程序不正确或者您有onLayout()错误的解决方案,请告诉我。
谢谢。