RecyclerView-获取所选位置并将该位置传递给另一个活动,在该活动中将显示相同的列表,并且选中了该特定项目

时间:2019-02-03 20:31:28

标签: java android android-intent android-recyclerview recycler-adapter

我已经为RecyclerView声明了一个适配器ViewModel.class,并且已经解析到MainActivity和另一个Activity,所以我为这两个活动使用了相同的适配器。

我可以在两个活动中都显示已解析的数据,但问题是我无法将所选项目的数据带到MainActivity,然后将其设置为btnSearch以便点击,这样我就可以在活动之间共享所选项目中的数据。

每次打开应用程序时,都会选择第一项。我想要实现的是。

  1. 将项目位置移至MainActivity,因此当我单击按钮进行搜索时,selectedItem的数据将进入intent.putExtra,然后在另一个Activity处获取数据。
  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.

onResume的{​​{1}}函数如下所示。

MainActivity

这是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)中。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分: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的{​​{1}}函数中删除与onResume相关的代码,以消除这种复杂性,因为我认为这是没有必要的。因此,更新后的MainActivity函数将如下所示。

onResume

更新3:

protected void onResume() { super.onResume(); searchPlugin.setText(""); getChangeColor(); } 中使用一个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

希望有帮助!