2017-08-16 23 views
2
  1. 我指的是vogella-tutorial结合数据绑定
  2. 什么,我试图做在回收视图检测的onClick:什么是使用检测的onClick在回收视图行对于每个项目的最佳方式数据绑定

activity_second.xml使用数据的Android

<?xml version="1.0" encoding="utf-8"?> 
<layout xmlns:android="http://schemas.android.com/apk/res/android"> 

    <data> 
     <variable 
      name="temp" 
      type="com.vogella.android.databinding.TemperatureData" /> 
     <variable 
      name="presenter" 
      type="com.vogella.android.databinding.MainActivityPresenter"/> 
    </data> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/my_recycler_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:scrollbars="vertical" /> 
</layout> 

rowlayout.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"> 

    <data> 

     <variable 
      name="obj" 
      type="com.vogella.android.databinding.TemperatureData" 
      /> 
    </data> 

    <RelativeLayout 
     android:layout_width="fill_parent" 
     android:layout_height="?android:attr/listPreferredItemHeight" 
     android:padding="6dip" 
     > 

     <ImageView 
      android:id="@+id/icon" 
      android:layout_width="wrap_content" 
      android:layout_height="fill_parent" 
      android:layout_alignParentBottom="true" 
      android:layout_alignParentTop="true" 
      android:layout_marginRight="6dip" 
      android:contentDescription="TODO" 
      android:src="@drawable/ic_listentry" 
      /> 

     <TextView 
      android:id="@+id/secondLine" 
      android:layout_width="fill_parent" 
      android:layout_height="26dip" 
      android:layout_alignParentBottom="true" 
      android:layout_alignParentRight="true" 
      android:layout_toRightOf="@id/icon" 
      android:ellipsize="marquee" 
      android:text="@{obj.location}" 
      android:textSize="12sp" 
      android:maxLines="1" 
     /> 

     <TextView 
      android:id="@+id/firstLine" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:layout_above="@id/secondLine" 
      android:layout_alignParentRight="true" 
      android:layout_alignParentTop="true" 
      android:layout_alignWithParentIfMissing="true" 
      android:layout_toRightOf="@id/icon" 
      android:gravity="center_vertical" 
      android:text="@{obj.celsius}" 
      android:textSize="16sp" 
      /> 

    </RelativeLayout> 

</layout> 

MyAdapter.java

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { 
     private List<TemperatureData> data; 

     // Provide a reference to the views for each data item 
     // Complex data items may need more than one view per item, and 
     // you provide access to all the views for a data item in a view holder 
     public class MyViewHolder extends RecyclerView.ViewHolder { 
       // each data item is just a string in this case 
       private final ViewDataBinding binding; 

       public MyViewHolder(ViewDataBinding binding) { 
         super(binding.getRoot()); 
         this.binding = binding; 
       } 
       public void bind(Object obj) { 
         binding.setVariable(BR.obj,obj); 
         binding.executePendingBindings(); 
       } 
     } 

     // Provide a suitable constructor (depends on the kind of dataset) 
     public MyAdapter(List<TemperatureData> myDataset) { 
       data = myDataset; 
     } 

     // Create new views (invoked by the layout manager) 
     @Override 
     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
       // create a new view 
       LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); 
       ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.rowlayout, parent, false); 
       // set the view's size, margins, paddings and layout parameters 
       return new MyViewHolder(binding); 
     } 

     // Replace the contents of a view (invoked by the layout manager) 
     @Override 
     public void onBindViewHolder(MyViewHolder holder, int position) { 
       final TemperatureData temperatureData = data.get(position); 
       holder.bind(temperatureData); 

     } 

     // Return the size of your dataset (invoked by the layout manager) 
     @Override 
     public int getItemCount() { 
      return data.size(); 
     } 

} 

MyAdapter.java

public class MyAdapter extends MyBaseAdapter { 

    List<TemperatureData> data; 

    // Provide a suitable constructor (depends on the kind of dataset) 
    public MyAdapter(List<TemperatureData> myDataset) { 
     data = myDataset; 
    } 
    @Override 
    public Object getDataAtPosition(int position) { 
     return data.get(position); 
    } 

    @Override 
    public int getLayoutIdForType(int viewType) { 
     return R.layout.rowlayout; 
    } 

    @Override 
    public int getItemCount() { 
     return data.size(); 
    } 
} 

回答

0

可能是最常见的解决方案将是把该行布局的根视图点击监听器,并呼吁您的视图模型的方法。 例如在rowlayout.xml:

... 
<RelativeLayout 
    android:onClick="@{() -> obj.performClickAction()}" 
.... 
+0

我试着说... Couldn没有发现事件....你试过吗? – Devrath

+0

是的,我通常会这样处理。你的问题更多的是调试,这应该工作。尝试在RelativeLayout上设置clickable = true,除此之外它只是一个调试问题,以查找未调用的内容。 – Ackerbar

+0

我认为它不能在listView中工作...在简单视图中工作 – Devrath

0

嘿,我读了一篇关于一个星期前,并有同样的问题!这篇文章几乎没有提到应该如何处理这些行为,但是如何做到这一点有documentation。总之,你会想要一个handler

这个处理器在XML定义

<data> 
    ... 
    <variable name="handlers" type="com.example.MyHandlers"/> 
    ... 
</data> 

例如使用

<TextView android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@{user.firstName}" 
     android:onClick="@{handlers::onClickFriend}"/> 

的MyHandlers.java是这样

public class MyHandlers { 
    public void onClickFriend(View view) { ... } 
} 

你会改变增加一个行到你的MyAdapter.java

public class MyViewHolder extends RecyclerView.ViewHolder { 
    public void bind(Object obj) { 
        binding.setVariable(BR.obj,obj); 
        binding.executePendingBindings(); 
        binding.setHandlers(new MyHandlers()); 
      } 

我还没有测试过这段代码,但如果这不起作用,我可以共享我的适配器。

+0

我应该在哪里定义'public class MyHandlers {public void onClickFriend(View view){...} } ....是否在Presenter ViewModel)....因为我需要在视图模型中执行一些操作,基于项目点击 – Devrath

+0

另外我无法设置处理程序 – Devrath

+0

为什么你不能添加处理程序?检查变量名是什么。我写的例子有名字处理程序 – Seabass77

0

不知道你是否已经找到了解决方案,但我设法很容易做到这一点。

1)修改onCreateViewHolder方法是这样的:

@Override 
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    // create a new view 
    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); 
    ViewDataBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.rowlayout, parent, false); 

    MainActivityPresenter presenter = new MainActivityPresenter(this, parent.getContext()); 
    binding.setVariable(BR.presenter,presenter); 

    // set the view's size, margins, paddings and layout parameters 
    return new MyViewHolder(binding); 
} 

2)使MyAdapter实现MainActivityContract.View所以最后它看起来像如下:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements MainActivityContract.View

3)实施必要的方法MyAdapter; e.g:

@Override 
public void showData(TemperatureData data) { 
    String clickedItemCelsius = data.getCelsius(); 
} 

4)演示变量添加到您的行布局文件:

<variable 
     name="presenter" 
     type="com.mvvm.ViewModels.MainActivityPresenter"/> 

5)最后挂钩的RelativeLayout根据你onClick事件:

<RelativeLayout 
    android:layout_width="fill_parent" 
    android:layout_height="?android:attr/listPreferredItemHeight" 
    android:padding="6dip" 
    android:onClick="@{() -> presenter.onShowData(obj)}" 
    > 

希望它能帮助!

0

这样我们就可以使用该项目的点击数据绑定 公共类CustomAdapter扩展RecyclerView.Adapter {

List<NewsModel> newsList; 
private LayoutInflater layoutInflater; 


public CustomAdapter(List<NewsModel> newsList) 
{ 
    this.newsList = newsList; 
} 

@Override 
public CustomView onCreateViewHolder(final ViewGroup parent, final int viewType) { 


    if(layoutInflater == null) 
    { 
     layoutInflater = LayoutInflater.from(parent.getContext()); 
    } 

    final NewsBinding newsBinding = NewsBinding.inflate(layoutInflater,parent,false); 

    newsBinding.setPresenter(new ClickListener() { 
     @Override 
     public void onclickListener() { 

      Log.d("click me ","click me "+newsBinding.getNewsview().Title); 
      Toast.makeText(parent.getContext(),""+newsBinding.getNewsview().Title,Toast.LENGTH_LONG).show(); 

     } 
    }); 

    // View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.innerlayout,parent,false); 
    return new CustomView(newsBinding); 
} 

@Override 
public void onBindViewHolder(CustomView holder, int position) { 

    // News news = newsList.get(position); 
    // holder.title.setText(news.getTitle()); 
    // holder.desc.setText(news.getDesc()); 

    NewsModel newsModel = newsList.get(position); 
    holder.bind(newsModel); 




} 

@Override 
public int getItemCount() { 
    return newsList.size(); 
} 

public class CustomView extends RecyclerView.ViewHolder { 

    private NewsBinding newsBinding; 
    // TextView title, desc; 
    public CustomView(NewsBinding newsBinding) { 
     super(newsBinding.getRoot()); 

     this.newsBinding = newsBinding; 
     //title = (TextView)itemView.findViewById(R.id.titleval); 
     //desc =(TextView)itemView.findViewById(R.id.descval); 

    } 

    public void bind(NewsModel newsModel) 
    { 
     this.newsBinding.setNewsview(newsModel); 
    } 

    public NewsBinding getNewsBinding() 
    { 
     return newsBinding; 
    } 

} 

}

完整的项目是https://github.com/Vishulucky/DataBinding-MVVM.git