繁体   English   中英

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

[英]How to pass data from recyclerview to new activity

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

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

公司:Company1 Company2 Company3 Company4 Company5

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

说明nipt俱乐部

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






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

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

在另一个活动中,您可以由此获取数据

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

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

让我们分析一下您有什么,对吧?

您的密码

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

问题

ListActivity无法将Company直接传递给CompanyDescription

你想做什么

  1. 将事物分解为较小的事物,因此您可以告诉事物仅执行“此事物,仅此而已”。 东西很多吗?
  2. 随时使用框架工具。

我会怎么做

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

在此应用程序的我的版本中,CompaniesRetriever是一个单例类(只能有一个类,例如Highlander ),因此,您无需在Description活动中执行new CompaniesRetriever() ,而只需使用 CompaniesList活动相同的实例即可。

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

现在,当用户点击列表中的一项时,您无需传递全部内容,而只需通过intent.putString("Id", selectedCompany.getId() )将公司的“ id”(或唯一的标识它的名称)传递给下一个活动intent.putString("Id", selectedCompany.getId() (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

希望这可以引导您朝更好的方向发展。

祝好运!

我会尝试这样做:

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

}

由于如此混乱,我找到了一种显示数据的简单方法,所以我决定不使用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());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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