私は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でOnClick
とOnLongClick
にバインドされていることです。 RecyclerView
のアイテムを短く長押しする方が良い方法があれば、間違ったやり方をしていると言えるでしょう。
RecyclerView全体に設定されているアイテムのクリックリスナーを行うのは反パターンです。代わりにアイテムごとのリスナーを実行します。私はここでデータバインディングを使ってアイテムごとの処理の例を投稿しました:http://stackoverflow.com/questions/42783116/what-is-the-recommended-way-to-launch-a-dialogfragment-from-a-viewmodel/42795719 #42795719 – Uli
@Uliあなたはこれを使用する要点やサンプルプロジェクトがありますか?それは良い解決策のように見えますが、私は両方の種類のクリックイベントを処理するためにどのように拡張できるか分かりません。あなたの例でSelectionListenerが何をしているのか分かりません。 –
完全な例はありませんが、拡張は簡単です。どこにでも "onClick"と書かれている場合は、 "onLongClick"を追加してください。 SelectionListenerは、クリックイベントをActivityまで伝播します。イベント・アクションでアクティビティー・レベルの機能が必要ない場合は、必要ありません。アダプターまたはViewHolderでクリックイベントを処理できます。あなたが何をしても、元々持っていた道をたどらないでください。あなたは私のような例を見つけることができるはずです、それはかなり標準です。 – Uli