如何通过SumCost方法为RecyclerView的textCost TextView设置文本?
如何在RecyclerView条目中通过SumCost方法为textCost TextView设置文本?
我创建了一个RecyclerView适配器,添加新条目时需要为两个TextView设置文本。其中id为text的TextView设置文本没有问题,请问如何通过以下SumCost方法为id为textCost的TextView设置文本?
private double SumCost(String result){ switch (result){ case "4820049490145": return 2.34; default: return 0; } }
String类型的result是从ScanPage页面获取的,完整代码如下:
activity_scan_page.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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=".MainActivity" android:orientation="vertical" android:padding="10dp"> <TextView android:id="@+id/SumText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="0.00" android:textSize="30sp"/> <Button android:id="@+id/scanBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Scan now" android:textSize="30sp" android:layout_gravity="center_horizontal"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout>
item.xml:
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_margin="10dp" app:cardCornerRadius="10dp" app:cardElevation="5dp" app:contentPadding="5dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:text="@string/app_name" android:textSize="20sp" /> <TextView android:id="@+id/textCost" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/text" android:text="@string/app_name" android:textSize="20sp" /> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:layout_marginTop="3dp" android:layout_marginEnd="3dp" android:text="Delete" /> </RelativeLayout> </androidx.cardview.widget.CardView>
ScanPage.java(在此获取IntentResult result,并通过items.add(result)设置android:id="@+id/text"):
package com.example.scanapp; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.app.ActionBar; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; import java.util.LinkedList; import java.util.List; public class ScanPage extends AppCompatActivity implements View.OnClickListener{ Button scanBtn; TextView editText; List<String> items = new LinkedList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan_page); scanBtn = findViewById(R.id.scanBtn); scanBtn.setOnClickListener(this); } public void AddItem(String result){ RecyclerView recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); DemoAdapter adapter = new DemoAdapter(items); recyclerView.setAdapter(adapter); items.add(result); } @Override public void onClick(View view) { scanCode(); } private void scanCode(){ IntentIntegrator integrator = new IntentIntegrator(this); integrator.setCaptureActivity(CaptureAct.class); integrator.setOrientationLocked(false); integrator.setDesiredBarcodeFormats(IntentIntegrator.ALL_CODE_TYPES); integrator.setPrompt("Scanning code"); integrator.initiateScan(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data); if(result != null){ if(result.getContents() != null){ AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(result.getContents()); builder.setTitle("Scanning Result"); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.cancel(); /// AddItem(result.getContents()); /// editText = (TextView) findViewById(R.id.SumText); editText.setText(Cost(SumCost(result.getContents()))); } }); AlertDialog dialog = builder.create(); dialog.show(); } else { Toast.makeText(this,"No result", Toast.LENGTH_LONG).show(); } } else { super.onActivityResult(requestCode, resultCode, data); } } //////// double SumVar = 0; private double SumCost(String result){ switch (result){ case "4820049490145": return 2.34; default: return 0; } } private String Cost(double cost){ SumVar += cost; return Double.toString(SumVar); } //////// }
DemoAdapter.java:
package com.example.scanapp; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.List; public class DemoAdapter extends RecyclerView.Adapter<DemoVH>{ List<String> items; public DemoAdapter(List<String> items){ this.items = items; } @NonNull @Override public DemoVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item, parent, false); return new DemoVH(view).linkAdapter(this); } @Override public void onBindViewHolder(@NonNull DemoVH holder, int position) { holder.textView.setText(items.get(position)); } @Override public int getItemCount() { return items.size(); } } class DemoVH extends RecyclerView.ViewHolder{ TextView textView; private DemoAdapter adapter; public DemoVH(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.text); itemView.findViewById(R.id.delete).setOnClickListener(view -> { adapter.items.remove(getAdapterPosition()); adapter.notifyItemRemoved(getAdapterPosition()); }); } public DemoVH linkAdapter(DemoAdapter adapter){ this.adapter = adapter; return this; } }
解决方案
按以下步骤修改代码即可实现需求:
1. 更新ViewHolder,添加textCost的引用
在DemoVH类中,新增对textCost TextView的绑定:
class DemoVH extends RecyclerView.ViewHolder{ TextView textView; TextView textCostView; // 新增引用 private DemoAdapter adapter; public DemoVH(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.text); textCostView = itemView.findViewById(R.id.textCost); // 初始化textCost控件 itemView.findViewById(R.id.delete).setOnClickListener(view -> { adapter.items.remove(getAdapterPosition()); adapter.notifyItemRemoved(getAdapterPosition()); }); } public DemoVH linkAdapter(DemoAdapter adapter){ this.adapter = adapter; return this; } }
2. 在Adapter中实现SumCost方法并绑定文本
把ScanPage中的SumCost方法复制到DemoAdapter中,然后在onBindViewHolder里计算并设置textCost的文本:
public class DemoAdapter extends RecyclerView.Adapter<DemoVH>{ List<String> items; public DemoAdapter(List<String> items){ this.items = items; } // 新增SumCost方法,与ScanPage中的逻辑一致 private double SumCost(String result){ switch (result){ case "4820049490145": return 2.34; default: return 0; } } @NonNull @Override public DemoVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item, parent, false); return new DemoVH(view).linkAdapter(this); } @Override public void onBindViewHolder(@NonNull DemoVH holder, int position) { String result = items.get(position); holder.textView.setText(result); // 计算金额并设置,格式化为两位小数提升显示效果 double cost = SumCost(result); holder.textCostView.setText(String.format("%.2f", cost)); } @Override public int getItemCount() { return items.size(); } }
3. 修复AddItem方法的性能问题
当前AddItem每次添加条目都会重新创建LayoutManager和Adapter,会造成不必要的性能损耗,修改为只初始化一次:
在ScanPage的onCreate方法中初始化RecyclerView:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan_page); scanBtn = findViewById(R.id.scanBtn); scanBtn.setOnClickListener(this); // 初始化RecyclerView,仅执行一次 RecyclerView recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); DemoAdapter adapter = new DemoAdapter(items); recyclerView.setAdapter(adapter); }
然后修改AddItem方法,仅更新数据并通知适配器:
public void AddItem(String result){ items.add(result); // 获取已初始化的适配器,通知新条目插入 RecyclerView recyclerView = findViewById(R.id.recyclerView); DemoAdapter adapter = (DemoAdapter) recyclerView.getAdapter(); adapter.notifyItemInserted(items.size() - 1); }
修改完成后,每次扫描添加条目时,textCost就会根据SumCost方法返回的金额显示对应内容。
内容的提问来源于stack exchange,提问作者Ribter
相关产品推荐
相关产品推荐

