Как реализовать SelectionTracker на Java не котлин - PullRequest
0 голосов
/ 25 апреля 2019

На Android я хочу, чтобы пользователи могли выбирать несколько строк из списка. Я прочитал, что могу использовать SelectionTracker с RecyclerView , чтобы включить выбор элементов списка .

Но все примеры кода на Kotlin. Есть ли примеры SelectionTracker в Java?

1 Ответ

0 голосов
/ 25 апреля 2019

Вот меню настроек, которое позволяет пользователю выбрать несколько настроек. Чтобы начать выбор, пользователь должен долго нажимать любую настройку. Затем они могут нажать любую настройку, чтобы выбрать больше.

Активность

package com.locuslabs.android.sdk;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.selection.ItemDetailsLookup;
import androidx.recyclerview.selection.Selection;
import androidx.recyclerview.selection.SelectionPredicates;
import androidx.recyclerview.selection.SelectionTracker;
import androidx.recyclerview.selection.StableIdKeyProvider;
import androidx.recyclerview.selection.StorageStrategy;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.gson.Gson;
import com.locuslabs.android.sdk.api.ConfigurationExperiments;
import com.locuslabs.android.sdk.api.MapExperiments;
import com.locuslabs.android.sdk.api.MapViewExperiments;
import com.locuslabs.android.sdk.api.PositionExperiments;
import com.locuslabs.android.sdk.api.VenueExperiments;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

public class SettingsActivity extends Activity {
    private static final String TAG = "SettingsActivity";
    SelectionTracker<Long> selectedSettingTracker;
    private RecyclerView settingsRecyclerView;
    private List<String> listOfUsableApis;
    private ApiSettings mApiSettings;

    private void setApiSettings(List<String> settingNamesSelected) {
        for (String settingName : settingNamesSelected) {
            if (settingName.equals(getResources().getString(R.string.api_setting_draw_line)))
                mApiSettings.mDrawLine = true;
            if (settingName.equals(getResources().getString(R.string.api_setting_search)))
                mApiSettings.mLogSearch = true;

            /* omitted rest of options for brevity */
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mApiSettings = new ApiSettings();

        setContentView(R.layout.activity_settings);

        settingsRecyclerView = findViewById(R.id.settingsRecyclerView);
        settingsRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        Button backButton = findViewById(R.id.settings_back_button);
        Button saveButton = findViewById(R.id.settings_apply_button);

        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setApiSettings(getSettingNamesSelected());
                Intent intent = new Intent();
                intent.putExtra("apiSettings", new Gson().toJson(mApiSettings));
                setResult(RESULT_OK, intent);
                finish();
            }
        });

        listOfUsableApis = /* omitted for brevity */

        final SettingsAdapter settingsAdapter = new SettingsAdapter();
        settingsRecyclerView.setAdapter(settingsAdapter);

        // Handle selection of settings
        selectedSettingTracker = new SelectionTracker.Builder<Long>(
                "selectedSettingTrackerId",
                settingsRecyclerView,
                new StableIdKeyProvider(settingsRecyclerView),
                new SettingsDetailsLookup(),
                StorageStrategy.createLongStorage()
        ).
                withSelectionPredicate(SelectionPredicates.<Long>createSelectAnything()).
                build();
    }

    private List<String> getSettingNamesSelected() {
        Selection<Long> settingsSelection = selectedSettingTracker.getSelection();
        Iterator<Long> settingSelectionIterator = settingsSelection.iterator();
        List<String> settingNamesSelected = new ArrayList<>();
        while (settingSelectionIterator.hasNext()) {
            Long settingSelectionId = settingSelectionIterator.next();
            String settingNameSelected = listOfUsableApis.get(settingSelectionId.intValue());
            settingNamesSelected.add(settingNameSelected);
        }
        return settingNamesSelected;
    }

    public static class ApiSettings {
        public boolean mDrawLine = false;
        public boolean mWalkSimulator = false;

        /* omitted most options for brevity */            

        public ApiSettings() {

        }
    }

    private class SettingsAdapter extends RecyclerView.Adapter<SettingsAdapter.SettingViewHolder> {
        public SettingsAdapter() {
            setHasStableIds(true);
        }

        @NonNull
        @Override
        public SettingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            TextView textView = (TextView) LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.setting_list_item, parent, false);
            SettingViewHolder settingViewHolder = new SettingViewHolder(textView);
            return settingViewHolder;
        }

        @Override
        public void onBindViewHolder(@NonNull SettingViewHolder holder, final int position) {
            holder.textView.setText(listOfUsableApis.get(position));
            holder.textView.setActivated(selectedSettingTracker.isSelected((long) position));
            holder.position = position;
        }

        @Override
        public int getItemCount() {
            return listOfUsableApis.size();
        }

        @Override
        public long getItemId(int position) {
            return Long.valueOf(position);
        }

        public class SettingViewHolder extends RecyclerView.ViewHolder {
            public int position;

            public TextView textView;

            public SettingViewHolder(TextView v) {
                super(v);
                textView = v;
            }
        }
    }

    private class SettingsDetailsLookup extends ItemDetailsLookup<Long> {

        @Nullable
        @Override
        public ItemDetails<Long> getItemDetails(@NonNull MotionEvent event) {
            View view = settingsRecyclerView.findChildViewUnder(event.getX(), event.getY());
            if (view != null) {
                final RecyclerView.ViewHolder viewHolder = settingsRecyclerView.getChildViewHolder(view);
                if (viewHolder instanceof SettingsAdapter.SettingViewHolder) {
                    final SettingsAdapter.SettingViewHolder settingViewHolder = (SettingsAdapter.SettingViewHolder) viewHolder;
                    return new ItemDetailsLookup.ItemDetails<Long>() {
                        @Override
                        public int getPosition() {
                            return viewHolder.getAdapterPosition();
                        }

                        @Nullable
                        @Override
                        public Long getSelectionKey() {
                            return Long.valueOf(settingViewHolder.position);
                        }
                    };
                }
            }
            return null;
        }
    }
}

Компоновка

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:baselineAligned="false"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#454545"
        android:weightSum="100">

        <Button
            android:id="@+id/settings_back_button"
            android:background="#454545"
            android:drawableStart="@drawable/arrow_white"
            android:drawableLeft="@drawable/arrow_white"
            android:layout_gravity="start"
            android:layout_width="@dimen/ll_mdu_10"
            android:layout_height="@dimen/ll_mdu_10"
            android:layout_weight="5"/>

        <Space
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="90"
            />

        <Button
            android:id="@+id/settings_apply_button"
            android:background="#454545"
            android:drawableStart="@android:drawable/ic_menu_save"
            android:drawableLeft="@android:drawable/ic_menu_save"
            android:layout_gravity="end"
            android:layout_width="@dimen/ll_mdu_10"
            android:layout_height="@dimen/ll_mdu_10"
            android:layout_weight="5"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingBottom="@dimen/activity_vertical_margin">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Long-press for first setting, then tap other settings for multiple selection"
            app:layout_constraintBottom_toTopOf="@+id/settingsRecyclerView"
            app:layout_constraintTop_toTopOf="parent" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/settingsRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView" />

    </LinearLayout>

</LinearLayout>

Макет setting_list_item.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/setting_list_item_text_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/setting_background"
    android:gravity="center_vertical"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    android:textAppearance="?android:attr/textAppearanceListItemSmall" />

Фон для рисования setting_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/holo_green_dark" android:state_activated="true" />
    <item android:drawable="@android:color/white" />
</selector>

Ссылки:

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