PageView 内的 Listview - NotifyDatasetChanged 未调用
Posted
技术标签:
【中文标题】PageView 内的 Listview - NotifyDatasetChanged 未调用【英文标题】:Listviews inside PageViewer - NotifyDatasetChanged not called 【发布时间】:2014-10-19 23:32:37 【问题描述】:我的列表视图快疯了。
我在 ViewPager 中有几个列表视图(每一个都不同)。
在每一行,我都有一个拍照按钮。我的列表视图中的所有数据都存储在 ArrayList 中,也存储在 Sqlite 中。在 onActivityResult,我在 db 中设置我的值,修改我用于适配器的 ArrayList,并调用 notifyDataSetChanged,以便我可以更改按钮图标(显示已拍摄的图片)。
我非常接近做到这一点。当我在 viewpager 中更改页面时,位图不会改变(因为未调用 getView),但是当我滚动列表视图以使行消失然后返回时,位图正在改变(因为我使用持有人模式,所以 getView 被调用。
我的适配器将变量 Metrica 作为参数:
public class Metrica
private int id;
private int clienteId;
private String description;
private int tipo;
private int proyectoProductoId;
private ArrayList<Formulario> lForms; // <-- this is the arraylist which populate the LV
[getters and setters...]
Formulario 对象:
public class Formulario
private int id;
private int capturaId;
private Producto producto;
private String cantidad; // qty
private String imagen; // pic
private boolean picTaken = false;
private int sync;
我的问题只是在我拍照的时候,即在onActivityResult中。
这是活动代码:
public class MetricaTabs extends ActionBarActivity implements
ActionBar.TabListener
static ArrayList<Metrica> lMetricas;
private SharedPreferences prefs;
public static Context ctx;
private int metricaId;
ActionBar actionBar;
static ListView lstForm;
Metrica metrica;
static EditText transparentEt;
FormsAdapter adbForm;
public static Uri imageFileUri;
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
private static int idCaptura;
private int mAction;
int numTab;
private final int TAKE_PIC_FORM = 1000;
ProgressDialog pd;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_metrica_tabs);
ctx = this;
FormHandler fh = new FormHandler(ctx);
MetricaHandler mh = new MetricaHandler(ctx);
// I should optimize this with a join
lMetricas = mh.getAllMetricas();
int i = 0;
for (Metrica m : lMetricas)
ArrayList<Formulario> lForms = fh.getAllForms(m.getId(), idCaptura);
lMetricas.get(i).setlForms(lForms);
i++;
fh.close();
mh.close();
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
@Override
public void onPageSelected(int position)
actionBar.setSelectedNavigationItem(position);
);
mSectionsPagerAdapter.notifyDataSetChanged();
// For each of the sections in the app, add a tab to the action
// bar.
for (int j = 0; j < mSectionsPagerAdapter.getCount(); j++)
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(j))
.setTabListener(MetricaTabs.this));
private void initDatos()
prefs = PreferenceManager.getDefaultSharedPreferences(this);
String activityName = getClass().getSimpleName().toString();
prefs.edit().putString("FrontActivity", activityName).commit();
idCaptura = prefs.getInt("capturaId", 0);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
switch (requestCode)
case TAKE_PIC_FORM:
if (resultCode == RESULT_OK)
mAction = TAKE_PIC_FORM;
int position = prefs.getInt("positionInList", 0);
metricaId = prefs.getInt("metricaId", 0);
String marca = prefs.getString("marca", null);
int proyectoproducto = prefs.getInt("proyectoproducto", 0);
String producto = prefs.getString("producto", null);
prefs.edit().remove("positionInList").commit();
prefs.edit().remove("metricaId").commit();
prefs.edit().remove("marca").commit();
prefs.edit().remove("producto").commit();
FormHandler fh = new FormHandler(ctx);
String picName = RutaActivity.getPicName(mAction, idCaptura,
metricaId, proyectoproducto);
Bundle extras = data.getExtras();
Bitmap bmp = (Bitmap) extras.get("data");
savePicture(mAction, bmp);
// Insert or update in sqlite
Formulario form = new Formulario();
form.setImagen(picName);
form.setCapturaId(idCaptura);
Producto p = new Producto();
p.setId(proyectoproducto);
p.setMarca(marca);
p.setMetricaId(metricaId);
p.setProducto(producto);
form.setProducto(p);
form.setSync(0);
boolean existForm = fh.existForm(form);
if (!existForm)
fh.addForm(form);
else
fh.updateForm(form);
metrica = lMetricas.get(numTab);
metrica.getlForms().set(position, form);
lMetricas.set(numTab, metrica);
// If I don't put this line, we work in the Adapter of the second Tab
adbForm = new FormsAdapter(this, 0, metrica, idCaptura);
adbForm.setMetrica(metrica);
adbForm.notifyDatasetChanged(); // <-- ### This doesn't do anything ###
fh.close();
break;
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(ctx);
numTab = tab.getPosition();
prefs.edit().putInt("numTab", numTab).commit();
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction)
/**
* Here we store the file url as it will be null after returning from camera
* app
*/
@Override
protected void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
// save file url in bundle as it will be null on scren orientation
// changes
outState.putParcelable("file_uri", imageFileUri);
/*
* Here we restore the fileUri again
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
super.onRestoreInstanceState(savedInstanceState);
// get the file url
imageFileUri = savedInstanceState.getParcelable("file_uri");
/**
* A @link FragmentPagerAdapter that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter
public SectionsPagerAdapter(android.support.v4.app.FragmentManager fm)
super(fm);
@Override
public android.support.v4.app.Fragment getItem(int position)
return PlaceholderFragment.newInstance(position);
@Override
public int getItemPosition(Object object)
return POSITION_NONE;
@Override
public int getCount()
if (lMetricas != null)
return lMetricas.size();
return 0;
@Override
public CharSequence getPageTitle(int position)
Locale l = Locale.getDefault();
return lMetricas.get(position).getDescription().toUpperCase(l);
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends
android.support.v4.app.Fragment
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String POSITION = "pos";
/**
* Returns a new instance of this fragment for the given section number.
*/
public static PlaceholderFragment newInstance(int numTab)
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(POSITION, numTab);
fragment.setArguments(args);
return fragment;
public PlaceholderFragment()
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_metrica_tabs,
container, false);
lstForm = (ListView) rootView.findViewById(R.id.list_form);
transparentEt = (EditText) rootView
.findViewById(R.id.transparentEt);
int numTab = getArguments().getInt(POSITION);
// Get the data
Metrica metrica = new Metrica();
if (lMetricas != null && lMetricas.size() > 0)
metrica = lMetricas.get(numTab);
FormsAdapter adbForm = new FormsAdapter(getActivity(), 0, metrica, idCaptura);
lstForm.setAdapter(adbForm);
adbForm.notifyDataSetChanged();
return rootView;
这是我使用支架模式的自定义适配器的完整代码:
公共类 FormsAdapter 扩展 ArrayAdapter 私有 ArrayList lForm; 私有上下文 ctx; 私有 int metricaId,capturaId; 私有公制公制; 公共静态 int TAKE_PIC_REQUEST = 1000; 私有 SharedPreferences 首选项;
public int getMetricaId()
return metricaId;
public void setMetricaId(int metricaId)
this.metricaId = metricaId;
public FormsAdapter(Context context, int textViewResourceId, Metrica met,
int cId)
super(context, textViewResourceId, met.getlForms());
setMetrica(met);
lForm = met.getlForms();
ctx = context;
prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
metricaId = getMetrica().getId();
capturaId = cId;
this.setlForm(lForm);
public int getViewTypeCount()
return getCount();
public int getItemViewType(int position)
return position;
public int getCount()
return getlForm().size();
public Formulario getItem(Formulario form)
return form;
public long getItemId(int position)
return position;
public static class ViewHolder
public TextView item;
public EditText valor;
public ImageView imgCam;
public Button listaCerrada;
public View getView(final int position, View convertView, ViewGroup parent)
final ViewHolder holder;
final String marca;
final String producto;
int tipo;
try
if (convertView == null)
holder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.row_lista_form, null);
tipo = getMetrica().getTipo();
holder.item = (TextView) convertView.findViewById(R.id.item);
holder.valor = (EditText) convertView.findViewById(R.id.valor);
holder.valor.setTag(position);
holder.listaCerrada = (Button) convertView
.findViewById(R.id.listaCerrada);
holder.listaCerrada.setTag(position);
if (tipo == 1)
holder.valor.setVisibility(View.VISIBLE);
holder.listaCerrada.setVisibility(View.GONE);
else
holder.valor.setVisibility(View.GONE);
holder.listaCerrada.setVisibility(View.VISIBLE);
holder.listaCerrada.getTag(position);
holder.imgCam = (ImageView) convertView
.findViewById(R.id.cambutton);
marca = getlForm().get(position).getProducto().getMarca();
producto = getlForm().get(position).getProducto().getProducto();
final int productoId = getlForm().get(position).getProducto()
.getId();
String valor = getlForm().get(position).getCantidad();
String datoValido = getlForm().get(position).getProducto()
.getDatoValido();
if (valor == null || valor.equals("null"))
valor = "";
holder.item.setText(marca + "\n" + producto);
holder.valor.setText(valor);
holder.listaCerrada.setText(valor);
holder.imgCam.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
prefs.edit().putInt("positionInList", position)
.commit();
prefs.edit().putInt("metricaId", metricaId).commit();
prefs.edit().putString("marca", marca).commit();
prefs.edit().putString("producto", producto).commit();
prefs.edit().putInt("proyectoproducto", productoId)
.commit();
takePic(TAKE_PIC_REQUEST);
);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
Formulario f = lForm.get(position);
String cantidad = f.getCantidad();
holder.valor.setText(cantidad);
holder.listaCerrada.setText(cantidad);
String fotoName = getlForm().get(position).getImagen();
if (fotoName != null)
Drawable myIcon = ctx.getResources().getDrawable(
R.drawable.ic_action_device_access_camera_done);
holder.imgCam.setImageDrawable(myIcon);
else
// holder.imgCam.setEnabled(true);
Drawable myIcon = ctx.getResources().getDrawable(
R.drawable.ic_action_device_access_camera);
holder.imgCam.setImageDrawable(myIcon);
catch (Exception e)
e.printStackTrace();
return convertView;
// Code : take pic request
private void takePic(int code)
MetricaTabs.imageFileUri = ctx.getContentResolver().insert(
Media.EXTERNAL_CONTENT_URI, new ContentValues());
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
((MetricaTabs) ctx).setResult(Activity.RESULT_OK, i);
((MetricaTabs) ctx).startActivityForResult(i, code);
public ArrayList<Formulario> getlForm()
return lForm;
public void setlForm(ArrayList<Formulario> lForm)
this.lForm = lForm;
public Metrica getMetrica()
return metrica;
public void setMetrica(Metrica metrica)
this.metrica = metrica;
任何帮助将不胜感激,我不知道如何解决这个问题,在这个问题上花了几天时间...... :(
【问题讨论】:
【参考方案1】:它单独解决,我不知道是什么原因,今天我运行了应用程序并且它正在工作......使用该代码。我不知道出了什么问题,但是......上帝存在!
【讨论】:
以上是关于PageView 内的 Listview - NotifyDatasetChanged 未调用的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 如何制作 PageView 和 ListView?
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套
采用cocos2d-x lua 的listview 实现pageview的翻页效果之上下翻页效果
jQuery Mobile Popup 和 ListView,以及 Popup div 内的 Knockout.js 数据绑定 - 不工作