Я объявил ViewModel.class для адаптера RecyclerView и проанализировал MainActivity и другой Activity, поэтому у меня есть один и тот же адаптер для обоих действий.
Я могу показать проанализированные данные в обоих действиях, но проблема в том, что я не могу передать данные выбранного элемента в MainActivity, а затем установить этот btnSearch для щелчка, чтобы затем я мог обмениваться данными между действиями. данные из выбранного элемента.
Каждый раз, когда приложение открыто, выбирается первый элемент. Чего я пытаюсь достичь, так это.
intent.putExtra, а затем получают данные в другом действии.Вот что я пробовал до сих пор.
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), когда я вернусь к нему.
Любая помощь будет оценена по достоинству.
@ReazMurshed Мне удалось отобразить список recyclerviewlist в обоих действиях, но я хочу, чтобы выбранный элемент отображался в MainActivity в btnSearch, а затем делился между основным действием и другим действием.
Пожалуйста, проверьте ответ и дайте мне знать, если это решит вашу проблему. Спасибо.
Я также изменил вопрос. Пожалуйста, отредактируйте и измените снова, если проблема не та же самая. Спасибо.
@ReazMurshed, я подумал, что вы тоже изменили вопрос.
Да, у меня есть. Пожалуйста, не стесняйтесь снова изменить свой вопрос, используя опцию edit, если это не описывает вашу проблему должным образом.
@ReazMurshed Я добавил еще один вопрос, не могли бы вы взглянуть. stackoverflow.com/questions/54536787/…




В вопросе было много изменений, и поэтому последнее обновление этого ответа ниже является окончательной версией.
Насколько я мог понять о проблеме, я вижу, что вы очень близки к решению, если я правильно понял. В 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);
Например, первый элемент выбирается автоматически, затем я выбираю второй элемент и нажимаю для перехода к другому действию, которое является ActivtiySearchEngine, затем снова выбран первый элемент, а не второй, и когда я нажимаю для возврата обратно в основное действие в MainActivity это второй выбранный.
Я смог это сделать, но только теперь у меня проблема, только когда я возобновляю работу с ActivitySearchEngine на MainActivity, он не получает selectedItem на ActivitySearchEngine.
Я обновил ответ. Пожалуйста, проверьте, помогает ли это.
Это помогает мне, но проблема в том, что когда я возобновляю MainActivity с ActivitySearchEngine, он не берет правильный selectedItem, который я выбрал для ActivitySearchEngine, он всегда занимает первый элемент.
Есть ли в вашем onResume какая-либо функция MainActivity? Если да, не могли бы вы поделиться кодом и обновить свой вопрос?
Да у меня есть функция onResume, сейчас обновлю вопрос.
Просто поместите функцию onResume в свой MainActivity.class и прокомментируйте здесь. Я посмотрю там.
Я только что обновился, и у меня есть еще один небольшой вопрос. Знаете ли вы, как сохранить выбранный элемент в общих настройках, чтобы каждый раз, когда я открывал приложение, он сообщал мне, что выбранный элемент не является первым выбранным элементом?
Пожалуйста, проверьте обновленный ответ. Дайте мне знать, если это поможет! Обратите внимание, что я удалил ненужные блоки кода из вопроса, чтобы он выглядел чистым и касался только проблемы.
он по-прежнему не работает. Я обновлю код, который я написал на данный момент, до MainActivity, и, как вы можете видеть, я изменил щелчок на адаптере.
Давайте продолжить обсуждение в чате.
С какой проблемой вы столкнулись? Пожалуйста, четко укажите, чего вы добились и в чем сейчас проблема. Спасибо.