gpt4 book ai didi

android - 滚动出屏幕后如何从回收 View 中的 View 中获取值

转载 作者:行者123 更新时间:2023-11-29 19:03:40 25 4
gpt4 key购买 nike

我有一个包含 RecyclerView 的 fragment 。这个 RecyclerView 将包含几种不同类型的 View (EditText、Seekbar、CheckBox 等),它将作为一种表单工作。我还有一个执行保存的按钮,它应该转到 RecyclerView 的每一行并获取用户输入的值。

我还有一个适配器,它根据我想在 RecyclerView 上添加的 View 类型来扩展不同的布局。在这个适配器中,我有一个“getValuesFromViews”方法,它根据 View 类型读取用户输入。

public String getValuesFromViews(int position,ViewHolder vHolder){
//...
}

在我的 fragment 中,在 For 循环期间,在使用 findViewHolderForAdapterPosition 获取 ViewHolder 之后,我调用了此方法

我的问题是,当我滚动我的 RecyclerView 时,我丢失了屏幕上未显示的位置的 ViewHolder,因此 findViewHolderForAdapterPosition 返回 null。

如何从屏幕上未显示的 View 中读取值?

编辑这是我目前的适配器(仍在开发中)。

public class ParamsAdapter extends RecyclerView.Adapter<ParamsAdapter.ViewHolder> {
private final android.support.v4.app.FragmentManager fragmentManager;
private final Fragment fragment;
private Context context;
private View view1;


ParamsAdapter.ViewHolder viewHolder1;
List<UserConfigurableParametersResponseMainItem1> listParams;

public ParamsAdapter(Context context1, List<UserConfigurableParametersResponseMainItem1> list, android.support.v4.app.FragmentManager fmanager, Fragment frag){
context = context1;
listParams = list;
fragmentManager = fmanager;
fragment = frag;
}

public List<UserConfigurableParametersResponseMainItem1> getListParams() {
return listParams;
}

public class ViewHolder extends RecyclerView.ViewHolder{

@BindView(R.id.tv_param_title)
TextViewMPOS tvParamTitle;
@BindView(R.id.iv_question)
ImageView ivQuestion;
@Nullable @BindView(R.id.et_param)
View param;
@BindView(R.id.param_loader)
AVLoadingIndicatorView loader;
@BindView(R.id.iv_status)
ImageView iv_status;
@BindView(R.id.iv_error)
ImageView iv_error;
@BindView(R.id.tv_param_error)
TextViewMPOS tvError;
@BindView(R.id.iv_reset)
ImageView ivReset;

public ViewHolder(View v){
super(v);
ButterKnife.bind(this,v);

}
}

@Override
public int getItemViewType(int position) {
return position;
}

@Override
public ParamsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){

view1 = createViews(parent,viewType);
viewHolder1 = new ParamsAdapter.ViewHolder(view1);

return viewHolder1;
}

private View createViews(ViewGroup parent, int viewType) {
ConfigurableParameterWebControlCode op = listParams.get(viewType).getParamWbCntrlCd();
switch (op){
case NUMERO:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_num,parent,false);
case DOUBLE:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_double,parent,false);
case EMAIL:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_email,parent,false);
case TEXTBOX:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_text,parent,false);
case TEXAREA:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_textarea,parent,false);
case SLIDER:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_slider,parent,false);
case CHECKBOX:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_num,parent,false);
case DROPDOWN:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_drop,parent,false);
case RADIOBUTTON:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_num,parent,false);
case DATA:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_data,parent,false);
case DATAHORA:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_datahora,parent,false);
case TEMPO:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_tempo,parent,false);
/* case PHONE:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_phone,parent,false);*/
case CHECKGROUP:
return LayoutInflater.from(context).inflate(R.layout.adapter_param_checkgroup,parent,false);
}

return null;
}

@Override
public void onBindViewHolder(final ParamsAdapter.ViewHolder holder, final int position){

final int index = getLanguageIndex(position);
holder.tvParamTitle.setText(listParams.get(position).getUsrCnfgrblPrmtrsRspnItms().get(index).getLablTxt());
holder.ivQuestion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(context != null)
MyDialogBuilder.createSingleButtonDialog(context,R.drawable.ic_warningcor,listParams.get(position).getUsrCnfgrblPrmtrsRspnItms().get(index).getHlprTxt(),R.string.ok,null,-1).show();
}
});
holder.ivReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
clearView(holder,position);
}
});

holder.iv_error.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(context != null)
MyDialogBuilder.createSingleButtonDialog(context,R.drawable.ic_errorcor,listParams.get(position).getUsrCnfgrblPrmtrsRspnItms().get(index).getErrTxt(),R.string.ok,null,-1).show();
}
});


switch (listParams.get(position).getParamWbCntrlCd()){

case NUMERO:
case DOUBLE:
case EMAIL:
case TEXTBOX:
case TEXAREA:
case TELEFONE:
EditTextMPOS editTextAux = (EditTextMPOS)holder.param;
if (editTextAux != null) {
editTextAux.setText(listParams.get(position).getParamVl());
}
break;
case SLIDER:
AppCompatSeekBar seekbarAux = (AppCompatSeekBar)holder.param;
seekbarAux.setMax(Integer.parseInt(listParams.get(position).getParamVldtnMax()));
seekbarAux.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
holder.tvParamTitle.setText(listParams.get(position).getUsrCnfgrblPrmtrsRspnItms().get(index).getLablTxt() +" "+i);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}
});
break;
case CHECKBOX:
break;
case DROPDOWN:
break;
case RADIOBUTTON:
break;

case DATA:
if (holder.param != null) {
holder.param.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyDialogBuilder.DialogDateNoHoursPicker(context,fragmentManager,fragment, DatePickerFragment.DATE_END,"# ",0);
}
});
}
break;
case DATAHORA:
if (holder.param != null) {
holder.param.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyDialogBuilder.DialogDatePicker(context,fragmentManager,fragment, DatePickerFragment.DATE_END,"##",0);
}
});
}
break;
case TEMPO:
if (holder.param != null) {
holder.param.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyDialogBuilder.DialogTimePicker(context,fragmentManager,fragment, DatePickerFragment.DATE_END,"###",0);
}
});
}
break;
case CHECKGROUP:
LinearLayout linearLayout = (LinearLayout)holder.param;
List<String> checkList = new ArrayList<String>(Arrays.asList(listParams.get(position).getParamVldtnRgExp().split(";")));
for(int i=0;i<checkList.size();i++){
CheckBox checkBox = new CheckBox(context);
checkBox.setText(checkList.get(i));
LinearLayout.LayoutParams newParams = new LinearLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
newParams.weight = 1;
checkBox.setLayoutParams(newParams);

linearLayout.addView(checkBox,i);
}
break;
}
}

private void clearView(ViewHolder holder, int position) {
switch (listParams.get(position).getParamWbCntrlCd()){
case NUMERO:
case DOUBLE:
case EMAIL:
case TEXTBOX:
case TEXAREA:
case TELEFONE:
EditTextMPOS auxView = (EditTextMPOS)holder.param;
if (auxView != null) {
auxView.setText("");
auxView.setHint(listParams.get(position).getDfltVl());
}
listParams.get(position).setUseDefault(true);
break;
case CHECKBOX:
break;
case DROPDOWN:
break;
case RADIOBUTTON:
break;
case DATA:
if (holder.param != null) {
holder.param.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyDialogBuilder.DialogDateNoHoursPicker(context,fragmentManager,fragment, DatePickerFragment.DATE_END,"# ",0);
}
});
}
break;
case DATAHORA:
if (holder.param != null) {
holder.param.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyDialogBuilder.DialogDatePicker(context,fragmentManager,fragment, DatePickerFragment.DATE_END,"##",0);
}
});
}
break;
case TEMPO:
if (holder.param != null) {
holder.param.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MyDialogBuilder.DialogTimePicker(context,fragmentManager,fragment, DatePickerFragment.DATE_END,"###",0);
}
});
}
break;
case CHECKGROUP:
break;
}
}

private int getLanguageIndex(int position) {
int index = 0;
String lang = HelperSharedPreferences.getSharedPreferencesString(context,HelperSharedPreferences.LANG,"pt-PT");
for (int i=0; i<listParams.get(position).getUsrCnfgrblPrmtrsRspnItms().size();i++) {
if(listParams.get(position).getUsrCnfgrblPrmtrsRspnItms().get(i).getLangCd().equals(lang)) {
index = i;
break;
}
}
return index;
}

public String getValuesFromViews(int position,ViewHolder vHolder){
String result = new String();
if(listParams.get(position).isUseDefault()) {
result = null;
}
else {
switch (listParams.get(position).getParamWbCntrlCd()) {
case NUMERO:
case DOUBLE:
case EMAIL:
case TEXTBOX:
case TEXAREA:
case TELEFONE:
EditTextMPOS auxView = (EditTextMPOS) vHolder.param;
if (auxView != null) {
result = auxView.getText().toString();
}
break;
case CHECKBOX:

break;
case CHECKGROUP:
LinearLayout linearLayout = (LinearLayout)vHolder.param;
for(int i = 0;i<linearLayout.getChildCount();i++){
if(((CheckBox)linearLayout.getChildAt(i)).isChecked()){
result += ((CheckBox)linearLayout.getChildAt(i)).getText() + ";";
}
}
break;

}
}
Logging.log("RESULT ",result);
return result;
}


public void setStatus(final int position, ViewHolder vHolder,int status){
if (status == 1) {
vHolder.iv_status.setVisibility(View.VISIBLE);
vHolder.iv_error.setVisibility(View.INVISIBLE);
vHolder.param.setBackgroundResource(R.drawable.edit_text_background);
} else if (status == 2) {
vHolder.iv_status.setVisibility(View.INVISIBLE);
vHolder.iv_error.setVisibility(View.VISIBLE);
vHolder.param.setBackgroundResource(R.drawable.edit_text_error_background);
} else {
vHolder.iv_status.setVisibility(View.INVISIBLE);
vHolder.iv_error.setVisibility(View.INVISIBLE);
if (vHolder.param != null) {
vHolder.param.setBackgroundResource(R.drawable.edit_text_background);
}
}
}


@Override
public int getItemCount(){
if(listParams != null)
return listParams.size();
else
return 0;
}

public void update (List<UserConfigurableParametersResponseMainItem1> list){
this.listParams.clear();
this.listParams = list;
setDataChanged();
}

public void setDataChanged(){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
}
}

我要创建它的数据是这样的数组

    {

"ParamCd":"xxxxxxx",
"ParamVl":"xxxxxxx",
"DfltVl":" ",
"ParamVldtnRgExp":".*",
"ParamWbCntrlCd":"EMAIL",
"ParamOrdr":54,
"UsrCnfgrblPrmtrsRspnItms":[
{
"LangCd":"pt-PT",
"LablTxt":"xxxxxxx",
"HlprTxt":"xxxxxxxxxxxxxx",
"ErrTxt":"xxxxxxxxxxxxxxxxxxxxx"
},
{
"LangCd":"en-UK",
"LablTxt":"xxxxxxx",
"HlprTxt":"xxxxxxxxxxxxxx",
"ErrTxt":"xxxxxxxxxxxxxxxxxxxxx"
}
]
}

字段“ParamWbCntrlCd”定义出现在 RecyclerView 行中的 View 类型

最佳答案

在 Android 中,适配器用于创建表示特定数据集的 View 。您可以将适配器视为数据显示 之间的一种桥梁。

因此,ViewHolder 是您的数据在给定位置的表示。由于 View 通常比纯数据占用更多内存,RecyclerView滚动时重复使用它们。这就是为什么您无法检索与滚出屏幕的 View 关联的数据的原因:那些 ViewHolder 已被回收,并且它们的 View 之前的状态已经丢失。

为了解决这个问题,我建议您执行以下步骤:

  1. 创建 SparseArray<UserConfigurableParametersResponseMainItem1>作为您的适配器的一个字段。这SparseArray将包含已被用户修改的模型对象的副本。
  2. 为其内容可以修改的 ViewHolders 中的每个 View 配置监听器。

对于每个有趣的变化,请调用 holder.getAdapterPosition()检索此 ViewHolder 在数据集中的当前位置。使用那个 position检查 SparseArray 中的这个位置是否存在对象.如果不存在,请在 listParams 的相同位置创建原始数据的副本。 .然后设置此对象的属性以反射(reflect)用户所做的更改。

想法是在适配器中维护用户所做修改的“缓存”。这样,用户所做的修改就不会再丢失。

  1. onBindViewHolder , 从给定的 position 中检索数据在稀疏数组中。如果是null , 则没有发出任何修改,您可以绑定(bind)来自 listParams 的数据.否则,用户已经进行了修改,您必须绑定(bind)那些而不是原来的。

  2. 创建方法 UserConfigurableParametersResponseMainItem1 getModificationsForPosition(int position) .此方法直接映射到 SparseArray 中包含的数据.这样,调用Fragment如果返回值不是 null,则直接知道会发生修改.

  3. 单击“保存”按钮时,使用 for 循环调用 getModificationsForPosition(i)对于适配器的每个有效位置,检索所有修改过的对象,然后将它们保存在任何你想要的地方(SQLite 或远程服务器)。

  4. 根据保存的更改刷新适配器的数据集。例如,您可以替换 listParams 中的数据与稀疏数组中的那些。单击“保存”按钮时,不要忘记清除稀疏数组。

该结构具有以下优点:

  • 即使在 ViewHolder 被回收后,对 View 的修改也会保留。
  • 可以为每个位置单独丢弃修改。
  • 只保存修改过的数据,效率更高。

希望对您有所帮助!

关于android - 滚动出屏幕后如何从回收 View 中的 View 中获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47979837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com