简体   繁体   中英

How to pass data from recyclerview to new activity

I'm trying to find a solution to pass data from my recyclerview adapter to new activity. I researched a lot but I didn't get a solution. I know that I need to use putExtra() but I don't know how.

The data is taken from API, I have displayed in the CompaniesListActivity but in this activity I want to show only name of the company and in the Company description I want to show the others. Like this:

Companies: Company1 Company2 Company3 Company4 Company5

and when I click to one of them I will get

description nipt clubs

activity_company_description.xml

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CompanyDescription">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/company_description"
        android:layout_width="395dp"
        android:layout_height="715dp"
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="8dp" />

</android.support.constraint.ConstraintLayout>

row_company_description.xml

    <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="160dp"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/row_padding_vertical"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/row_padding_vertical">

    <TextView
        android:id="@+id/tvCompanyDescription"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="3dp"
        android:layout_marginEnd="8dp"
        android:text="TextView"
        android:textSize="12sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.023"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvCompanyName" />

    <TextView
        android:id="@+id/tvCompanyNipt"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="3dp"
        android:layout_marginEnd="8dp"
        android:text="TextView"
        android:textSize="12sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvCompanyDescription" />

    <TextView
        android:id="@+id/tvClubs"
        android:layout_width="wrap_content"
        android:layout_height="15dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:text="TextView"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tvCompanyNipt"
        app:layout_constraintVertical_bias="0.2"
        tools:layout_editor_absoluteX="5dp" />

</android.support.constraint.ConstraintLayout>

my recyclerview adapter

    private Context context;

    public CompanyAdapter(Context context, Companies companies) {
        this.companies = companies;
        this.context = context;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.row_companies, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int position) {
        final Company comp = companies.getCompanies().get(position);

        viewHolder.compName.setText(comp.getCompany().getName());
        viewHolder.compDesc.setText(comp.getCompany().getDescription());
        viewHolder.compNipt.setText(comp.getCompany().getNipt());
        viewHolder.compClubs.setText(comp.getClubs().toString());

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Company selectedCom = companies.getCompanies().get(position);
                Intent intent = new Intent(context, CompanyDescription.class);
                intent.putExtra("company", selectedCom);
                intent.putExtra("description", comp);
                intent.putExtra("nipt", comp);
                intent.putExtra("clubs", comp);
                context.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() {
        Integer rows = companies == null ? 0 : companies.getCompanies().size();
        return rows;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public TextView compName, compDesc, compNipt, compClubs;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            compName = (TextView) itemView.findViewById(R.id.tvCompanyName);
            compDesc = (TextView) itemView.findViewById(R.id.tvCompanyDescription);
            compNipt = (TextView) itemView.findViewById(R.id.tvCompanyNipt);
            compClubs = (TextView) itemView.findViewById(R.id.tvClubs);

        }

    }

my CompaniesListActivity-> 

    private RecyclerView recyclerView;
    private RecyclerView.Adapter adapter;
    private UserService service;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_companies_list);
        CompaniesRetriver companiesRetriver = new CompaniesRetriver();
        this.recyclerView = (RecyclerView) findViewById(R.id.companies_list);
        SharedPreferences editor = getSharedPreferences(MY_PREFERENCE, MODE_PRIVATE);
        String token = editor.getString("token", "");
        final Context sfdsf = this;
        Callback<Companies> callback = new Callback<Companies>() {
            @Override
            public void onResponse(Call<Companies> call, Response<Companies> response) {
                if(response.isSuccessful()) {
                    Companies companies = response.body();
                    CompanyAdapter adapter = new CompanyAdapter(CompaniesListActivity.this, companies);
                    recyclerView.setLayoutManager(new LinearLayoutManager(CompaniesListActivity.this));
                    recyclerView.setAdapter(adapter);
                    System.out.println(companies);
                } else {
                    System.out.println(response.body());
                }
            }

            @Override
            public void onFailure(Call<Companies> call, Throwable t) {

                System.out.println(t.getLocalizedMessage());
            }
        };

        companiesRetriver.getCompanies(callback, token);

        recyclerView.addItemDecoration(
                new DividerItemDecoration(ContextCompat.getDrawable(getApplicationContext(),
                        R.drawable.item_separator)));
    }

and CompanyDescriptionActivity

   super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_company_description);
        Company ind = (Company) getIntent().getSerializableExtra("company");
        System.out.println(ind);
        CompaniesRetriver companiesRetriver = new CompaniesRetriver();
        this.recyclerView = (RecyclerView) findViewById(R.id.company_description);






try this one hope its helpfull to you.

 Intent intent = new Intent(context, CompanyDescription.class);
            intent.putExtra("key", value);
            context.startActivity(intent);

and in Another activity you can get data by this

String value=getIntent().getStringExtra("key");

What you're describing is a problem with your Separation of Concerns here.

Let's analyze what you have, shall we?

Your Code

You have 2 activities. One fetches a list of data from an API, and displays it in a list (which involves creating the adapter and satisfying all the requirements for the list to display). This activity also serves as your data repository to the rest of the activities, since you store this list here, in the list activity. The other activity is intended to display the Details (or in your case "Description") of an Item (or in your example a Company ).

Problem

You have no way for the ListActivity to directly pass a Company to CompanyDescription

What you want to do

  1. Separate things into smaller things, so you can tell a thing only does "this thing and nothing more". A lot of things huh?
  2. Use the framework tools at your disposal.

What I would do

  1. CompanyListActivity should only be in charge of the list; to display it and construct it, that's all it needs to know about it.
  2. CompanyListActivity will inflate the XML (for the RecyclerView), will create an adapter and will request the data to a repository (you have it called CompaniesRetriever ) So Companies Retriever will let the activity know when there's data (you already did this, since you pass a callback). There is an issue with your implementation, if the user loads this list and then immediately hits back, I don't see any code in the CompanyListActivity to inform the retriever that the data is no longer needed (since the user left the activity). Keep an eye for that, because if you're passing any context to said "retriever", you may have a memory leak waiting to happen.
  3. So far so good. Now you have your list. And here is where we both do things differently:

In my version of this app, CompaniesRetriever is a singleton class (there can be only one, like Highlander ), and so instead of doing new CompaniesRetriever() in the Description activity, you simply use the same instance that the CompaniesList activity used.

This opens a new possibility, when the Retriever (which we cannot see because you didn't share the code) receives the API callback with the data and it's ready to pass it back to the CompaniesList (in the callback you have), it instead keeps a local copy of this data and then passes it along.

Now when the user TAPS an item on the list, instead of passing the whole thing, you simply pass the "id" of the Company (or something unique to identify it) to the next activity via the intent.putString("Id", selectedCompany.getId() (the id can be anything you want as long as it allows the next activity to uniquely identify it).

In the NEXT activity, you obtain the "selected company id" and you call your Retriever (which has a list of all the companies in memory), with a new method whose signature looks like: public Company getCompanyById(String id) (pseudo code obviosuly)

The all the retriever does is:

public Company getCompanyById(String id) {
      listofCompanies.get(id) // I would use a hashMap for faster lookup
}

(if you use a list instead you will need to iterate until you find what you're looking for, if you have 1000 companies, that's fine, if you expect a HUGE number, consider a hashmap or a faster data structure)

In any case, the end result is that your new "Description" activity doesn't need to worry too much about anything, it receives an ID and it asks for the data.

This keeps both activities oblivious to the origin of the data, they are simply given the data they need (the flow is mostly in one direction, which is good). Activities ASK for data, don't supply it.

I hope this helps you re-think your code, you wouldn't need to make a lot of changes, for you already have most of the things in place.

How about the XML?!

I'm not 100% sure what you mean by accessing the XML from "there" (your words), but I think you don't need it, because what you were thinking was to read the XML from the company you are displaying in the list, and that is not possible (literally) and unneeded with the architecture I'm proposing (which, for the record, I didn't invent) :D

Hope this guides you in a better direction.

Good luck!

I would try to do it like this:

private Context context;
private onItemClickListener;

public CompanyAdapter(OnItemClickListener listener, Companies companies) {
    this.companies = companies;
    this.onItemClickListener = listener;
}

 public interface OnItemClickListener {
void OnItemClick(Companies companies)
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.row_companies, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int position) {
    final Company comp = companies.getCompanies().get(position);
  viewHolder.bind(comp, onItemClickListener);
}

@Override
public int getItemCount() {
    Integer rows = companies == null ? 0 : companies.getCompanies().size();
    return rows;
}

public class ViewHolder extends RecyclerView.ViewHolder {

    public TextView compName, compDesc, compNipt, compClubs;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        compName = (TextView) itemView.findViewById(R.id.tvCompanyName);
        compDesc = (TextView) itemView.findViewById(R.id.tvCompanyDescription);
        compNipt = (TextView) itemView.findViewById(R.id.tvCompanyNipt);
        compClubs = (TextView) itemView.findViewById(R.id.tvClubs);

    }

   public void bind (Companies comp, OnItemClickListener listener) {

compName.setText(comp.getCompany().getName());             
   compDesc.setText(comp.getCompany().getDescription());
compNipt.setText(comp.getCompany().getNipt());
compClubs.setText(comp.getClubs().toString());

itemView.setOnClickListener(new View.OnClickListener() {
  @Override
public void onClick(View v) {

onItemClickListener.OnItemClick(comp);
Context context = v.getContext;
            Intent intent = new Intent(context, CompanyDescription.class);
            intent.putExtra("company", selectedCom);
            intent.putExtra("description", comp);
            intent.putExtra("nipt", comp);
            intent.putExtra("clubs", comp);
            context.startActivity(intent);
        }
    });
   }

}

With so much confusion I found a simple way how to display the data, I decided not use recyclerview but something simpler. All is working fine now.

Intent intent = getIntent();
    company = (Company) intent.getSerializableExtra("company");

    tvCompanyName = (TextView) findViewById(R.id.tvCompanyName);
    tvCompanyDescription = (TextView) findViewById(R.id.tvCompanyDescription);
    tvCompanyNipt = (TextView) findViewById(R.id.tvCompanyNipt);

    tvCompanyName.setText(company.getCompany().getName());
    tvCompanyDescription.setText(company.getCompany().getDescription());
    tvCompanyNipt.setText(company.getCompany().getNipt());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM