2016-04-06 5 views
1

Я пытаюсь следовать this example, чтобы создать WearableListView. У меня проблема с файлом BoxInsetLayout, потому что я получаю ошибку onLayout(), пытаясь отобразить макет. Вот трассировки стека:onLayout error с WearableListView

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 реализован, но я получаю нулевой 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

Я не думаю, что ваша вторая ошибка возникает из-за ошибки ошибки 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) { 

       } 
      }; 
     } 
    } 
} 

После этого modifiy файл 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> 
+0

Благодарим за помощь. Я опубликовал ответ прямо сейчас с исправлением, которое я нашел. –

+0

Рад, что вы исправили свою проблему с нулевым WearableList, так как для проблем onLayout() мое решение разрешает его, если вы заинтересованы в нем. – mhlsf

+0

Я отметил это как решение. Спасибо еще раз за помощь. –

0

мне удалось решить мою проблему с нулевым объектом WearableListView следующего this example, но я забыл опубликовать ответ на корм э. То, что я сделал это пошевелить расположение WearableListView в файл round_activity_devices_list.xml (потому что мое устройство круглая, но я думаю, что это должно работать на Rect устройстве тоже, если я добавить свой макет в rect_activity_devices_list.xml):

<?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(), сообщите мне.

спасибо.