如何将数据从Recyclerview传递到新活动

时间:2019-06-12 09:16:14

标签: java android

我正在尝试找到一种解决方案,以将数据从我的recyclerview适配器传递到新活动。我做了很多研究,但没有找到解决方案。 我知道我需要使用putExtra(),但我不知道如何。

数据取自API,我已显示在CompaniesListActivity中,但在此活动中我仅想显示公司名称,在Company描述中我想显示其他名称。 像这样:

公司: 公司1 公司2 公司3 公司4 公司5

当我单击其中一个时,我会得到

说明 nip 俱乐部

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>

我的recyclerview适配器

    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);






4 个答案:

答案 0 :(得分:2)

尝试这个希望对您有所帮助。

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

在另一个活动中,您可以通过此操作获取数据

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

答案 1 :(得分:0)

您要描述的是此处的关注分离问题。

让我们分析一下您拥有什么,好吗?

您的代码

您有2个活动。其中一个从API获取数据列表,并将其显示在列表中(这涉及创建适配器并满足显示列表的所有要求)。此活动还用作其余活动的数据存储库,因为您将此列表存储在列表活动中。 其他活动旨在显示项目(或在您的示例中为Company)的详细信息(在您的情况下为“描述”)。

问题

ListActivity无法将Company直接传递给CompanyDescription

你想做什么

  1. 将事物分解为较小的事物,因此您可以说一个事物只会执行“此事物,仅此而已”。有很多东西吗?
  2. 使用框架工具供您使用。

我会做什么

  1. CompanyListActivity应该只负责列表;展示并构建它,这就是它所需要知道的全部。
  2. CompanyListActivity将为RecyclerView扩充XML,创建适配器 ,并将数据请求到存储库(您将其命名为CompaniesRetriever),因此Companies Retriever将允许活动知道何时有数据(由于已经传递了回调,因此您已经做到了)。您的实现存在问题,如果用户加载此列表然后立即回击,则在CompanyListActivity中看不到任何代码来通知检索器不再需要数据(因为用户离开了活动)。请注意这一点,因为如果您将任何上下文传递给所说的“猎犬”,则可能会发生内存泄漏。
  3. 到目前为止一切顺利。现在您有了清单。这是我们俩做事不同的地方:

在此应用程序的我的版本中,CompaniesRetriever是一个单例类(只能有一个,例如Highlander),因此您无需在Description活动中进行new CompaniesRetriever(),而只需使用<公司列表活动使用的em>相同的实例。

这打开了一种新的可能性,即当检索器(由于未共享代码而无法看到)接收到带有数据的API回调并将其传递回CompaniesList(在您拥有的回调中)时, ,它会保留此数据的本地副本,然后将其传递。

现在,当用户点击列表中的一个项目时,无需传递整个内容,您只需通过intent.putString("Id", selectedCompany.getId()将公司的“ id”(或唯一的标识它的名称)传递给下一个活动(ID可以是您想要的任何东西,只要它允许下一个活动唯一标识它即可。)

在NEXT活动中,您将获得“选定的公司ID”,并使用一种签名如下的新方法调用您的检索器(该记录中有所有公司的列表):public Company getCompanyById(String id)(伪的代码)

检索器所做的全部是:

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

(如果您使用列表,则需要进行迭代,直到找到所需的内容;如果有1000家公司,那很好,如果希望有巨大的数字,请考虑使用哈希表或更快的数据结构)

无论如何,最终结果是您新的“描述”活动无需过多担心任何事情,它会收到一个ID,并询问数据。

这使两个活动都不必理会数据的来源,只是给了它们所需的数据即可(流大多在一个方向上,这很好)。活动要求提供数据,请不要提供。

我希望这可以帮助您重新考虑您的代码,因为您已经准备好了大多数东西,所以无需进行很多更改。

XML怎么样?!

我不确定100%从“那里”(您的话)访问XML的意思,但是我认为您不需要它,因为您的想法是从您所在的公司读取XML正显示在列表中,这是不可能的(从字面上看),也不是我所提议的体系结构所必需的(据记录,我没有发明):D

希望这会为您提供更好的指导。

祝你好运!

答案 2 :(得分:0)

我会尝试这样做:

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);
        }
    });
   }

}

答案 3 :(得分:0)

由于如此混乱,我找到了一种显示数据的简单方法,所以我决定不使用recyclerview而是使用更简单的方法。现在一切正常。

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());