0

我已經得到了一個相當不錯的Android數據綁定掛起,但我堅持在我的應用程序中,我還沒有能夠與數據綁定綁定的最後一件事。我有一個RecyclerView我已經實現了一個自定義觸摸監聽器來處理短點擊和長時間點擊。我只是不確定我應該綁定什麼。甚至可以使用onItemTouchListener的數據綁定?我會粘貼我的代碼,並希望有人能告訴我應該試圖綁定什麼,或者如果甚至有一點,我可以指出正確的方向。Android數據綁定與RecyclerView自定義onItemTouchListener

觸摸監聽器:

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

我的目標是產生OnClick和OnLongClick在XML綁定莫名其妙

我會去兩個不同的接口,如果我是你。但這只是一個品味問題。要綁定它,你需要一個結合銜接頭:

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

,當然,你的RecyclerViewTouchListener,應申報二傳手爲RecyclerViewClickListener。在你的佈局中,你應該有類似的東西

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