0

私はAndroid Data Bindingのかなりのハングアップを得ていますが、私はまだデータバインディングでバインドできなかったアプリで最後のことに取り残されています。私はRecyclerViewを持っていますが、私は短いクリックと長いクリックを処理するカスタムタッチリスナを実装しています。私はちょうど私が縛ると思われるものがわからない。 onItemTouchListenerのデータバインディングを使用することも可能ですか?私が持っているコードを貼り付けて、誰かが正しい方向に私を縛り付けようとしているべきことを教えてくれるか、それともポイントがあるかどうかを教えてくれることを願っています。RecyclerViewカスタムwithItemTouchListenerでAndroidデータバインド

タッチリスナー:

public class RecyclerViewTouchListener implements RecyclerView.OnItemTouchListener 
{ 
    private RecyclerViewClickListener clickListener; 
    private GestureDetector gestureDetector; 

    public RecyclerViewTouchListener(Context context, final RecyclerView recycleView, final RecyclerViewClickListener cl) 
    { 
     this.clickListener = cl; 
     gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() 
     { 
      @Override 
      public boolean onSingleTapUp(MotionEvent e) 
      { 
       return true; 
      } 

      @Override 
      public void onLongPress(MotionEvent e) 
      { 
       View child = recycleView.findChildViewUnder(e.getX(), e.getY()); 
       if (child != null && cl != null) 
       { 
        cl.onLongClick(child, recycleView.getChildAdapterPosition(child)); 
       } 
      } 
     }); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) 
    { 
     View child = rv.findChildViewUnder(e.getX(), e.getY()); 
     if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) 
     { 
      clickListener.onClick(child, rv.getChildAdapterPosition(child)); 
     } 

     return false; 
    } 

    @Override 
    public void onTouchEvent(RecyclerView rv, MotionEvent e) 
    { 
    } 

    @Override 
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) 
    { 
    } 
} 

クリックリスナー:

public interface RecyclerViewClickListener 
{ 
    void onClick(View view, int position); 
    void onLongClick(View view, int position); 
} 

現在のxml:

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

    <data> 
     <variable 
      name="activity" 
      type="com.redacted.ListActivity"/> 
    </data> 

    <android.support.design.widget.CoordinatorLayout 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     xmlns:tools="http://schemas.android.com/tools" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:fitsSystemWindows="true" 
     tools:context="com.redacted.ListActivity"> 

     <android.support.design.widget.AppBarLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:theme="@style/AppTheme.AppBarOverlay"> 

      <android.support.v7.widget.Toolbar 
       android:id="@+id/toolbar" 
       android:layout_width="match_parent" 
       android:layout_height="?attr/actionBarSize" 
       android:background="?attr/colorPrimary" 
       app:popupTheme="@style/AppTheme.PopupOverlay"/> 

     </android.support.design.widget.AppBarLayout> 

     <android.support.constraint.ConstraintLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      app:layout_behavior="@string/appbar_scrolling_view_behavior"> 

      <android.support.v7.widget.RecyclerView 
       android:id="@+id/listRv" 
       android:layout_width="0dp" 
       android:layout_height="0dp" 
       android:layout_marginBottom="8dp" 
       android:layout_marginTop="8dp" 
       app:layout_constraintBottom_toBottomOf="parent" 
       app:layout_constraintLeft_toLeftOf="parent" 
       app:layout_constraintRight_toRightOf="parent" 
       app:layout_constraintTop_toTopOf="parent"/> 
     </android.support.constraint.ConstraintLayout> 


     <com.github.clans.fab.FloatingActionButton 
      xmlns:fab="http://schemas.android.com/apk/res-auto" 
      android:id="@+id/addItemFab" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:onClick="@{activity::fabClicked}" 
      android:layout_gravity="bottom|end" 
      android:layout_margin="@dimen/fab_margin" 
      android:src="@drawable/ic_add" 
      fab:fab_colorNormal="@color/colorAccent" 
      fab:fab_colorPressed="@color/colorAccentLight" 
      fab:fab_size="normal"/> 

    </android.support.design.widget.CoordinatorLayout> 
</layout> 

マイアクティビティ:

public class ListActivity extends AppCompatActivity 
{ 
    private OrderedRealmCollection<MyObject> allItems; 
    private Realm realm; 
    private ActivityListBinding b; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     b = DataBindingUtil.setContentView(this, R.layout.activity_list); 
     b.setActivity(this); 

     setSupportActionBar(b.toolbar); 

     realm = Realm.getDefaultInstance(); 

     CreateViewModel(); 

     b.listRv.setHasFixedSize(true); 
     b.listRv.setAdapter(new ListAdapter(allItems, true)); 
     b.listRv.setLayoutManager(new LinearLayoutManager(this)); 

     b.listRv.addOnItemTouchListener(new RecyclerViewTouchListener(this, 
       b.listRv, new RecyclerViewClickListener() 
     { 
      @Override 
      public void onClick(View view, final int position) 
      { 
       //unimportant code 
      } 

      @Override 
      public void onLongClick(View view, int position) 
      { 
       //unimportant code 
      } 
     })); 
    } 

    private void CreateViewModel() 
    { 
     ListViewModel vm = new ListViewModel(realm); 
     allItems = vm.getAllItems(); 
    } 

    @Override 
    protected void onDestroy() 
    { 
     super.onDestroy(); 
     b.listRv.setAdapter(null); 
     realm.close(); 
    } 

    public void fabClicked(View view) 
    { 
     //unimportant code 
    } 
} 

私の目標は、何とかXMLでOnClickOnLongClickにバインドされていることです。 RecyclerViewのアイテムを短く長押しする方が良い方法があれば、間違ったやり方をしていると言えるでしょう。

+1

RecyclerView全体に設定されているアイテムのクリックリスナーを行うのは反パターンです。代わりにアイテムごとのリスナーを実行します。私はここでデータバインディングを使ってアイテムごとの処理の例を投稿しました:http://stackoverflow.com/questions/42783116/what-is-the-recommended-way-to-launch-a-dialogfragment-from-a-viewmodel/42795719 #42795719 – Uli

+0

@Uliあなたはこれを使用する要点やサンプルプロジェクトがありますか?それは良い解決策のように見えますが、私は両方の種類のクリックイベントを処理するためにどのように拡張できるか分かりません。あなたの例でSelectionListenerが何をしているのか分かりません。 –

+0

完全な例はありませんが、拡張は簡単です。どこにでも "onClick"と書かれている場合は、 "onLongClick"を追加してください。 SelectionListenerは、クリックイベントをActivityまで伝播します。イベント・アクションでアクティビティー・レベルの機能が必要ない場合は、必要ありません。アダプターまたはViewHolderでクリックイベントを処理できます。あなたが何をしても、元々持っていた道をたどらないでください。あなたは私のような例を見つけることができるはずです、それはかなり標準です。 – Uli

答えて

0

私の目標は、クリック時とOnLongClickは私があなたにあった場合、私は、二つの異なるインターフェースのために行くだろう何とか

XMLにバインドすることです。しかし、それは味の問題です。 RecyclerViewClickListener用セッターを宣言する必要があり、

@SuppressWarnings("unchecked") 
@BindingAdapter("onItemClickListener") 
public static <T> void setOnItemClickListener(RecyclerView recyclerView, RecyclerViewClickListener clickListener) { 
    if (recyclerView instanceof RecyclerViewTouchListener) { 
     ((RecyclerViewTouchListener) recyclerView).setItemClickListener(clickListener); 
    } 
} 

と、もちろん、あなたのRecyclerViewTouchListener:それをバインドするには、結合アダプタが必要。あなたのレイアウトでは、あなたは何かを持っているはずです

<your.package.to.RecyclerViewTouchListener 
     app:onItemClickListener="@{yourViewModel.getRecyclerViewClickListener()}"