2017-08-16 25 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