Есть ли способ перетаскивать предметы без касания и удерживать предмет в Android RecycleView - PullRequest
0 голосов
/ 29 октября 2019

Я создаю простую игру-анаграмму с использованием android studio, и я хочу, чтобы пользователь переставлял слова с помощью перетаскивания в представлении реселлера или listView в Android. Но я не хочу, чтобы пользователь касался и удерживал его перед перетаскиванием представления, я хочу, чтобы представление было перетаскиваемым сразу, когда пользователь касается его.

Я следовал примеру кода drag_and_reorder из github здесь: https://github.com/trulymittal/RecyclerView/tree/drag_and_reorder но требуется, чтобы пользователь коснулся и удерживал представление перед перемещением элементов

открытый класс PlayGame расширяет AppCompatActivity {

RecyclerView recyclerView;
RecyclerAdapter recyclerAdapter;

List<String> moviesList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_play_game);

// Панель инструментов панели инструментов = findViewById (R. id.toolbar);// setSupportActionBar (панель инструментов);

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);


    moviesList = new ArrayList<>();
    moviesList.add("A");
    moviesList.add("N");
    moviesList.add("A");
    moviesList.add("G");
    moviesList.add("R");
    moviesList.add("A");
    moviesList.add("M");


    recyclerView = findViewById(R.id.recyclerView);
    recyclerAdapter = new RecyclerAdapter(moviesList);
    recyclerView.setAdapter(recyclerAdapter);

    DividerItemDecoration dividerItemDecoration = new 
    DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
    recyclerView.addItemDecoration(dividerItemDecoration);

    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView);




}




ItemTouchHelper.SimpleCallback simpleCallback = new 
ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | 
ItemTouchHelper.START | ItemTouchHelper.END, 0) {
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull 
    RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder 
     target) {

        int fromPosition = viewHolder.getAdapterPosition();
        int toPosition = target.getAdapterPosition();
        Collections.swap(moviesList, fromPosition, toPosition);
        recyclerView.getAdapter().notifyItemMoved(fromPosition, 
         toPosition);
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int 
      direction) {

    }

};

}

1 Ответ

0 голосов
/ 30 октября 2019

Конечно, здесь один 100-строчный код в пределах одного Activity и импорта, представляющий все это поведение даже с простой анимацией.

enter image description here

class MainActivity : AppCompatActivity() {

    @Volatile
    var state : State = State.INACTIVE

    enum class State {
        ACTIVE, INACTIVE, HANDLED
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        bind()
    }

    private fun bind() {
        addQuestions()
        addAnswers()
    }

    private fun getRandomColor(): Int {
        return Color.argb(255, Random.nextInt(255),
            Random.nextInt(255), Random.nextInt(255))
    }

    @SuppressLint("InflateParams")
    private fun addQuestions() {
        val inflater = getSystemService(
            Context.LAYOUT_INFLATER_SERVICE
        ) as LayoutInflater
        for (i in 1..8) {
            val view = inflater.inflate(R.layout.item_question, null)
            view.findViewById<View>(R.id.questionView)
                .setOnDragListener(DragListener())
            questionContainer.addView(view)
        }
    }


    @SuppressLint("InflateParams")
    private fun addAnswers() {
        val inflater = getSystemService(
            Context.LAYOUT_INFLATER_SERVICE
        ) as LayoutInflater
        for (i in 1..8) {
            val view = inflater.inflate(R.layout.item_answer, null)
            (view as ViewGroup).getChildAt(0).setBackgroundColor(getRandomColor())
            view.setOnTouchListener(DragItemTouchListener())
            answerContainer.addView(view)
        }
    }

    private inner class DragItemTouchListener : OnTouchListener {
        val ITEM_INDEX_D = "Index-From"

        override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
            return if (motionEvent.action == MotionEvent.ACTION_DOWN) {
                createDrag(view)
                true
            } else {
                false
            }
        }

        private fun createDrag(view : View) {
            val parent = view.parent as ViewGroup
            view.tag = Pair(ITEM_INDEX_D,
                parent.indexOfChild(view))

            view.startDragAndDrop(ClipData.newPlainText("", ""),
                DragShadowBuilder(view), view, 0)
            parent.removeView(view)
            parent.setBackgroundColor(Color.WHITE)
        }
    }

    private inner class DragListener : OnDragListener {

        override fun onDrag(parent: View, event: DragEvent): Boolean {
            val view = event.localState as View

            when (event.action) {
                DragEvent.ACTION_DRAG_STARTED -> {
                    state = State.ACTIVE
                }
                DragEvent.ACTION_DRAG_ENTERED -> {
                }
                DragEvent.ACTION_DRAG_EXITED -> {

                }
                DragEvent.ACTION_DROP -> {
                    state = State.HANDLED
                    animateDropEffect(parent, view)
                    return true
                }
                DragEvent.ACTION_DRAG_ENDED -> {
                    if (state == State.ACTIVE) {
                        state = State.INACTIVE
                        animateMoveBack(view,
                            (view.tag as Pair<*, *>).second as Int)
                    }
                    return true
                }
                else -> {
                }
            }
            return true
        }

        private fun animateMoveBack(view: View, index : Int) {
            answerContainer.addView(view, index)
        }

        private fun animateDropEffect(into: View, view: View) {
            val parent = (into.parent as ViewGroup)
            parent.addView(view)

            val params = (view.layoutParams as FrameLayout.LayoutParams)
                .apply {
                    gravity = Gravity.END
                }
            view.layoutParams = params
            checkIsCorrect(parent)
        }

        private fun checkIsCorrect(parent : ViewGroup) {
            val correct = Random.nextBoolean()

            val colorFrom = Color.WHITE
            val colorTo : Int = if (correct) 0x8000ff00.toInt() else 0x80ff0000.toInt()
            ObjectAnimator.ofObject(
                parent,
                "backgroundColor",
                ArgbEvaluator(),
                colorFrom,
                colorTo
            )
                .setDuration(1000)
                .start()
        }
    }
}

Все использованные Xmls. Ниже xml для всех примеров ниже.

/* activity_main.xml */
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    android:id="@+id/mainContainer"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">


        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="500dp"
            android:animateLayoutChanges="true">

            <LinearLayout
                android:id="@+id/questionContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:animateLayoutChanges="true"
                android:orientation="vertical">

            </LinearLayout>
        </ScrollView>

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:animateLayoutChanges="true">

            <LinearLayout
                android:id="@+id/answerContainer"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:animateLayoutChanges="true"
                android:orientation="horizontal">

            </LinearLayout>
        </HorizontalScrollView>

    </LinearLayout>
</FrameLayout>


/* item_question.xml */
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:padding="5dp">

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="start"
        android:background="@android:color/holo_blue_bright">

    </View>

    <View
        android:id="@+id/questionView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="end"
        android:background="@android:color/holo_orange_light">

    </View>

</FrameLayout>


/* item_answer.xml */
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="5dp"
    android:tag="Test">


    <LinearLayout
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:background="@android:color/darker_gray">

    </LinearLayout>

</FrameLayout>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...