- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个包含 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 之前的状态已经丢失。
为了解决这个问题,我建议您执行以下步骤:
SparseArray<UserConfigurableParametersResponseMainItem1>
作为您的适配器的一个字段。这SparseArray将包含已被用户修改的模型对象的副本。对于每个有趣的变化,请调用 holder.getAdapterPosition()
检索此 ViewHolder 在数据集中的当前位置。使用那个 position
检查 SparseArray
中的这个位置是否存在对象.如果不存在,请在 listParams
的相同位置创建原始数据的副本。 .然后设置此对象的属性以反射(reflect)用户所做的更改。
想法是在适配器中维护用户所做修改的“缓存”。这样,用户所做的修改就不会再丢失。
在 onBindViewHolder
, 从给定的 position
中检索数据在稀疏数组中。如果是null
, 则没有发出任何修改,您可以绑定(bind)来自 listParams
的数据.否则,用户已经进行了修改,您必须绑定(bind)那些而不是原来的。
创建方法 UserConfigurableParametersResponseMainItem1 getModificationsForPosition(int position)
.此方法直接映射到 SparseArray
中包含的数据.这样,调用Fragment
如果返回值不是 null
,则直接知道会发生修改.
单击“保存”按钮时,使用 for 循环调用 getModificationsForPosition(i)
对于适配器的每个有效位置,检索所有修改过的对象,然后将它们保存在任何你想要的地方(SQLite 或远程服务器)。
根据保存的更改刷新适配器的数据集。例如,您可以替换 listParams
中的数据与稀疏数组中的那些。单击“保存”按钮时,不要忘记清除稀疏数组。
该结构具有以下优点:
希望对您有所帮助!
关于android - 滚动出屏幕后如何从回收 View 中的 View 中获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47979837/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!