RecyclerView - получить выбранную позицию и передать ее другому действию, где будет отображаться тот же список с выбранным конкретным элементом

Я объявил ViewModel.class для адаптера RecyclerView и проанализировал MainActivity и другой Activity, поэтому у меня есть один и тот же адаптер для обоих действий.

Я могу показать проанализированные данные в обоих действиях, но проблема в том, что я не могу передать данные выбранного элемента в MainActivity, а затем установить этот btnSearch для щелчка, чтобы затем я мог обмениваться данными между действиями. данные из выбранного элемента.

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

  1. Получите позицию элемента в MainActivity, поэтому, когда я нажимаю кнопку поиска, данные выбранного элемента передаются в intent.putExtra, а затем получают данные в другом действии.
  2. Если я нажму второй элемент и перейду к другому действию, будет выбран тот же элемент.

Вот что я пробовал до сих пор.

SearchEngineAdapter.class

public class SearchEngineAdapter extends RecyclerView.Adapter<SearchEngineAdapter.ViewHolder> {
    private int selectedItem = 0;
    private static RecyclerViewClickListener itemListener;

    private Context context;
    ArrayList<SearchEngine> arrayList = new ArrayList<>();

    public SearchEngineAdapter(Context context, ArrayList<SearchEngine> arrayList, int selectedItem) {
        this.context = context;
        this.arrayList = arrayList;
        this.selectedItem = selectedItem;
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int i) {
        holder.tvIcon.setImageResource(arrayList.get(i).getIcon());
        holder.tvId.setText(arrayList.get(i).getId());
        holder.tvSearchUrl.setText(arrayList.get(i).getUrl());
        final String url = holder.tvSearchUrl.getText().toString();

        SharedPreferences sp = context.getSharedPreferences("SavedSelected", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt("selected", selectedItem);
        editor.apply();

        sp = context.getSharedPreferences("SavedSelected", Context.MODE_PRIVATE);
        int myIntValue = sp.getInt("selected", -1);
        Log.d("Selected", "SharedPreferences" + myIntValue);

        if (selectedItem == i) {
            holder.tvIcon.setBackgroundColor(Color.parseColor("#30000000"));
            Intent intent = new Intent("search_engines");
            intent.putExtra("url", url);
            intent.putExtra("selected", selectedItem);
            LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
        } else {
            holder.tvIcon.setBackgroundColor(Color.parseColor("#00000000"));
        }

        holder.tvIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("search_engines");
                intent.putExtra("url", url);
                int PreviousSelectedItem = selectedItem;
                selectedItem = i;
                intent.putExtra("selected", selectedItem);
                holder.tvIcon.setBackgroundColor(Color.parseColor("#30000000"));
                notifyItemChanged(PreviousSelectedItem);
                notifyDataSetChanged();
            }
        });
    }

    // ... Other necessary functions.
}

Теперь MainActivity.class

RecyclerView paramRecyclerView;
SearchEngineAdapter sEngineAdapter;

paramRecyclerView = findViewById(R.id.lvEngines);
paramRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
paramRecyclerView.setHasFixedSize(true);
Intent intent = getIntent();
int intValue = intent.getIntExtra("selected", 0);
sEngineAdapter = new SearchEngineAdapter(context, arrayList, intValue);
paramRecyclerView.setAdapter(sEngineAdapter);

// Calling network APIs to populate the arrayList.

Функция onResumeMainActivity выглядит следующим образом.

protected void onResume() {
    super.onResume();
    searchPlugin.setText("");
    getChangeColor();
}

Это обработчик кликов, определенный в MainActivity, который отправляет меня в другое действие.

btnSearch.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String newEntry = searchPlugin.getText().toString();
        AddHistory(newEntry);
        getFragmentRefreshListener().onRefresh();
        Intent intent = new Intent(MainActivity.this, ActivitySearchEngine.class);
        intent.putExtra("url", url );
        intent.putExtra("name", newEntry);
        intent.putExtra("selected", selectedItem2);
        startActivity(intent);
    }
});

И другая активность ActivitySearchEngine.class

public class ActivitySearchEngine extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {

    public String selectedName;
    public int selectedID;
    public String selectedSearchUrl;
    RecyclerView mListView;
    RecyclerView paramRecyclerView;
    SearchEngineAdapter sEngineAdapter;

    ArrayList<SearchEngine> arrayList = new ArrayList<>();
    final Context context = this;
    int selectedItem;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search_result);

        // Variables initialization

        // Setting up adapter
        paramRecyclerView.setAdapter(sEngineAdapter);
        sEngineAdapter.notifyDataSetChanged();

        // Calling network APIs to populate the arrayList here

        Intent receivedIntent = getIntent();
        selectedName = receivedIntent.getStringExtra("name");
        selectedID = receivedIntent.getIntExtra("id", 1); //NOTE: -1 is just the default value
        selectedSearchUrl = receivedIntent.getStringExtra("url");

        // Loading the url in a WebView for searching
    }
}

Я мог бы разделить позицию выбранного элемента между этими двумя действиями. Однако я не уверен, как добиться поведения элемента, выбираемого в RecyclerView второго действия. Если я выберу другой элемент в RecyclerView второго действия, изменение должно быть отражено и в первом (т.е. MainActivity), когда я вернусь к нему.

Любая помощь будет оценена по достоинству.

С какой проблемой вы столкнулись? Пожалуйста, четко укажите, чего вы добились и в чем сейчас проблема. Спасибо.

Reaz Murshed 04.02.2019 00:09

@ReazMurshed Мне удалось отобразить список recyclerviewlist в обоих действиях, но я хочу, чтобы выбранный элемент отображался в MainActivity в btnSearch, а затем делился между основным действием и другим действием.

Abedin.Zhuniqi 04.02.2019 00:20

Пожалуйста, проверьте ответ и дайте мне знать, если это решит вашу проблему. Спасибо.

Reaz Murshed 04.02.2019 20:20

Я также изменил вопрос. Пожалуйста, отредактируйте и измените снова, если проблема не та же самая. Спасибо.

Reaz Murshed 04.02.2019 20:27

@ReazMurshed, я подумал, что вы тоже изменили вопрос.

Abedin.Zhuniqi 04.02.2019 21:48

Да, у меня есть. Пожалуйста, не стесняйтесь снова изменить свой вопрос, используя опцию edit, если это не описывает вашу проблему должным образом.

Reaz Murshed 04.02.2019 23:55

@ReazMurshed Я добавил еще один вопрос, не могли бы вы взглянуть. stackoverflow.com/questions/54536787/…

Abedin.Zhuniqi 05.02.2019 15:40
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
7
4 266
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Насколько я мог понять о проблеме, я вижу, что вы очень близки к решению, если я правильно понял. В SearchEngineAdapter уже есть переменная selectedItem, которую также можно использовать для выделения элемента, выбранного в ActivitySearchEngine. Вам просто нужно немного изменить адаптер, как показано ниже. Я переписываю адаптер здесь.

public class SearchEngineAdapter extends RecyclerView.Adapter<SearchEngineAdapter.ViewHolder> {
    private int selectedItem = 0;
    private static RecyclerViewClickListener itemListener;

    private Context context;
    ArrayList<SearchEngine> arrayList = new ArrayList<>();

    // Added another argument to be passed in the constructor
    public SearchEngineAdapter(Context context, ArrayList<SearchEngine> arrayList, int selectedItem) {
        this.context = context;
        this.arrayList = arrayList;
        this.selectedItem = selectedItem;
    }

    @NonNull
    @Override
    public SearchEngineAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(context).inflate(R.layout.s_engine_item, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int i) {
        if (selectedItem == i) {
            holder.tvIcon.setBackgroundColor(Color.parseColor("#30000000"));
        } else {
            holder.tvIcon.setBackgroundColor(Color.parseColor("#00000000"));
        }

        holder.tvIcon.setImageResource(arrayList.get(i).getIcon());
        holder.tvId.setText(arrayList.get(i).getId());
        holder.tvSearchUrl.setText(arrayList.get(i).getUrl());

        holder.tvIcon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int PreviousSelectedItem = selectedItem;
                selectedItem = i;
                holder.tvIcon.setBackgroundColor(Color.parseColor("#30000000"));
                notifyItemChanged(PreviousSelectedItem);
                notifyDataSetChanged();
            }
        });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder{
        TextView tvId, tvSearchUrl;
        ImageView tvIcon;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            tvId = itemView.findViewById(R.id.ivEngineText);
            tvIcon = itemView.findViewById(R.id.ivEngine);
            tvSearchUrl = itemView.findViewById(R.id.ivSearchUrl);
        }
    }
}

Убедитесь, что я только что изменил конструктор вашего адаптера, взяв еще одну дополнительную переменную selectedItem. Просто передайте позицию выбранного элемента при инициализации адаптера в обоих действиях. В случае по умолчанию вы можете передать -1, я думаю, вы поняли идею.

Вы также передали позицию выбранного элемента в ActivitySearchEngine. Который можно использовать для инициализации желаемого поведения. Надеюсь, это поможет!

Обновление 1:

Я хотел бы предложить вам поместить следующий код в вашу функцию onResume в классе ActivitySearchEngine. Вы также можете рассмотреть возможность удаления строк из функции onCreate вашего кода.

@Override
public void onResume() {
    super.onResume();

    Intent receivedIntent = getIntent();
    selectedName = receivedIntent.getStringExtra("name");
    selectedID = receivedIntent.getIntExtra("id", 1); // NOTE: -1 is just the default value
    selectedSearchUrl = receivedIntent.getStringExtra("url");

    sEngineAdapter = new SearchEngineAdapter(context, arrayList, selectedID);
    paramRecyclerView.setAdapter(sEngineAdapter);
}

Обновление 2:

RecyclerView в вашем MainActivity перезагружается, когда вы снова настраиваете адаптер на RecyclerView в функции onResume. Более того, вы пытаетесь получить данные из намерения, которых здесь нет, я думаю, потому что вы не установили какие-либо данные для отправки на MainActivity, когда вы вернетесь обратно с ActivitySearchEngine. Следовательно, RecyclerView снова перезагружается со свежим набором данных.

Вы можете удалить код, связанный с вашим RecyclerView, из функции onResumeMainActivity, чтобы устранить эту сложность, поскольку я думаю, что в этом нет необходимости. Итак, обновленная функция onResume будет выглядеть следующим образом.

protected void onResume() {
    super.onResume();
    searchPlugin.setText("");
    getChangeColor();
}

Обновление 3:

Возьмите переменную public static в вашем MainAcitivity и объявите ее как глобальную переменную, как показано ниже.

// Setting 0 as you wanted to put the first item at the first time
// If you do not want that, then initialize with -1
public static int selectedItem = 0; 

Теперь внутри вашей функции onCreate удалите строки для получения intent.

paramRecyclerView = findViewById(R.id.lvEngines);
paramRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
paramRecyclerView.setHasFixedSize(true);

// Remove the following
// Intent intent = getIntent();
// int intValue = intent.getIntExtra("selected", 0);

// Move the adapter setup to the onResume
// sEngineAdapter = new SearchEngineAdapter(context, arrayList, selectedItem);
// paramRecyclerView.setAdapter(sEngineAdapter);

// Calling network APIs to populate the arrayList.

Измените функцию onResume в MainActivity, чтобы настроить там адаптер.

protected void onResume() {
    super.onResume();
    searchPlugin.setText("");
    getChangeColor();

    // Set the adapter here 
    sEngineAdapter = new SearchEngineAdapter(context, arrayList, selectedItem);
    paramRecyclerView.setAdapter(sEngineAdapter);
}

Измените onClickListener в вашем адаптере следующим образом. Просто добавьте туда новую строку.

holder.tvIcon.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent("search_engines");
        intent.putExtra("url", url);
        int PreviousSelectedItem = selectedItem;
        selectedItem = i;

        // Set the static value in the MainActivity 
        // This can be accessed from all other classes
        MainActivity.selectedItem = i;

        intent.putExtra("selected", selectedItem);
        holder.tvIcon.setBackgroundColor(Color.parseColor("#30000000"));
        notifyItemChanged(PreviousSelectedItem);
        notifyDataSetChanged();
    }
});

Надеюсь, это поможет!

Как мне получить выбранный элемент для другого действия, которое я написал что-то вроде этого, но если я щелкну второй элемент и из основного действия перейду к другому действию, это снова останется первым элементом, на который нажали? sEngineAdapter = new SearchEngineAdapter(context, arrayList, 0);

Abedin.Zhuniqi 04.02.2019 21:54

Например, первый элемент выбирается автоматически, затем я выбираю второй элемент и нажимаю для перехода к другому действию, которое является ActivtiySearchEngine, затем снова выбран первый элемент, а не второй, и когда я нажимаю для возврата обратно в основное действие в MainActivity это второй выбранный.

Abedin.Zhuniqi 04.02.2019 22:03

Я смог это сделать, но только теперь у меня проблема, только когда я возобновляю работу с ActivitySearchEngine на MainActivity, он не получает selectedItem на ActivitySearchEngine.

Abedin.Zhuniqi 04.02.2019 23:20

Я обновил ответ. Пожалуйста, проверьте, помогает ли это.

Reaz Murshed 04.02.2019 23:55

Это помогает мне, но проблема в том, что когда я возобновляю MainActivity с ActivitySearchEngine, он не берет правильный selectedItem, который я выбрал для ActivitySearchEngine, он всегда занимает первый элемент.

Abedin.Zhuniqi 05.02.2019 00:02

Есть ли в вашем onResume какая-либо функция MainActivity? Если да, не могли бы вы поделиться кодом и обновить свой вопрос?

Reaz Murshed 05.02.2019 00:11

Да у меня есть функция onResume, сейчас обновлю вопрос.

Abedin.Zhuniqi 05.02.2019 00:13

Просто поместите функцию onResume в свой MainActivity.class и прокомментируйте здесь. Я посмотрю там.

Reaz Murshed 05.02.2019 00:13

Я только что обновился, и у меня есть еще один небольшой вопрос. Знаете ли вы, как сохранить выбранный элемент в общих настройках, чтобы каждый раз, когда я открывал приложение, он сообщал мне, что выбранный элемент не является первым выбранным элементом?

Abedin.Zhuniqi 05.02.2019 00:15

Пожалуйста, проверьте обновленный ответ. Дайте мне знать, если это поможет! Обратите внимание, что я удалил ненужные блоки кода из вопроса, чтобы он выглядел чистым и касался только проблемы.

Reaz Murshed 05.02.2019 00:21

он по-прежнему не работает. Я обновлю код, который я написал на данный момент, до MainActivity, и, как вы можете видеть, я изменил щелчок на адаптере.

Abedin.Zhuniqi 05.02.2019 00:26

Давайте продолжить обсуждение в чате.

Reaz Murshed 05.02.2019 00:30

Другие вопросы по теме