如何在Java中而不是Kotlin中实现SelectionTracker

时间:2019-04-25 04:42:14

标签: java android kotlin

在Android上,我希望用户能够从列表中选择多行。我听说可以将SelectionTrackerRecyclerView to enable list-item selection结合使用。

但是所有代码示例都在Kotlin中。 Java中有SelectionTracker的示例吗?

1 个答案:

答案 0 :(得分:0)

这里是设置菜单,允许用户选择多个设置。要开始选择,用户必须长按任何设置。然后他们可以点击任何设置以选择更多。

活动

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>

参考文献: