我正在视图持有者/适配器模式之后创建“文档”的网格视图.在活动中,我从网络类中获得回调,因此我需要能够在不同的时间更新每个网格单元.
我这样做的方法是通过从对象元素(文档)到相应的视图持有者的映射映射.我需要这样做,因为适配器正在循环使用单元格,所以有时我可以收到一个回调来更新一个不可见的单元格,在这种情况下,回调信息将被忽略.
我可以看到适配器的getView方法被多次调用为位置0.我一直在读这是正常的.
- inflating position 0 *** progressBar 1
- recycling position 0
- recycling position 0
- inflating position 0 *** progressBar 2
- recycling position 0
- recycling position 0
- recycling position 0
- recycling position 0
- recycling position 0
- recycling position 0
我需要从回调中更新的一个UI元素是一个进度条,我通过将viewHolder添加到与文档关联的Map来跟踪.
除了第一个方法之外,这整个方法适用于所有位置.我可以识别的唯一区别是这些多次调用getView所以我从那里开始调试.我正在更新的progressBar是“progressBar 2”,这是geView膨胀的最新版本,但实际上它并没有响应setVisible(View.VISIBLE).然后我对代码进行了一些更改以更新“progressBar 1”并且它可以工作.
这意味着getView在同一位置膨胀两次,但第二次没有被使用或显示.
我能做错什么?为什么progressbar1工作而progressbar2没有?我希望getView会给我一个与位置相对应的最新视图.
谢谢.
适配器:
- public class DocumentPickerGridViewAdapter extends ArrayAdapter<Document> implements Filterable {
- private final DocumentPickerGridViewController picker;
- private ArrayList values;
- private ArrayList filtered;
- private LayoutInflater inflater;
- public DocumentPickerGridViewAdapter(Context context,ArrayList values) {
- super(context,R.id.documentPickerGridView,values);
- this.picker = (DocumentPickerGridViewController) context;
- this.filtered = values;
- this.values = (ArrayList)values.clone();
- inflater = (LayoutInflater) picker.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
- @Override
- public View getView(int position,View convertView,ViewGroup parent) {
- View v = convertView;
- ViewHolder oldHolder;
- ViewHolder holder;
- Document doc = (Document) filtered.get(position);
- if (v == null) {
- v = inflater.inflate(R.layout.documentpickergriditem,parent,false);
- holder = new ViewHolder();
- holder.actionView = (Button) v.findViewById(R.id.document_action_button);
- holder.coverView = (ImageView) v.findViewById(R.id.documentCoverImage);
- holder.archiveButton = (Button) v.findViewById(R.id.document_archive_button);
- holder.progressView = (ProgressView) v.findViewById(R.id.documentProgress);
- holder.progressBar = (ProgressBar) v.findViewById(R.id.documentCoverImageProgressBar);
- picker.allProgressViews.add(holder);
- Log.d("MARIANO","adding to allProgressViews "+holder.progressView);
- Log.d("MARIANO","inflating position "+position);
- v.setTag(holder);
- }
- else{
- // here we are recycling,we should clean old stuff.
- holder = (ViewHolder)v.getTag();
- synchronized (picker){
- oldHolder = picker.documentHoldersMap.get(holder.doc);
- }
- if(oldHolder != null){
- oldHolder.progressView.setVisibility(View.GONE);
- oldHolder.progressBar.setVisibility(View.GONE);
- }
- // Document associated with prevIoUs holder it's now out of the adapter visible window.
- // we have to remove it from the map so if picker receives any call back we won't update anything.
- if(! holder.doc.uuid().equals(doc)){
- synchronized (picker){
- picker.documentHoldersMap.remove(holder.doc);
- }
- }
- }
- holder.doc = doc;
- holder.position = position;
- synchronized (picker){
- picker.documentHoldersMap.put(doc,holder);
- }
- /*
- TODO: check why view extendedGrid starts to measure the size of the grid after gridpicker view has disapear. This causes a ArrayOutofIndexes
- exception. DocumentGridPicker view does setDocuments(null); which clears all arrays,but the adapter stays setting as many cells as before.
- https://kaldorgroup.jira.com/browse/NEWSWEEK-49
- */
- if(picker.documents() != null && picker.documents().size() > 0 ){
- picker.setCoverView(holder.coverView,doc);
- picker.setActionButton(holder.actionView,doc);
- picker.setArchiveButton(holder.archiveButton,doc);
- picker.refreshButton(doc);
- }
- TextView textView = (TextView) v.findViewById(R.id.documentName);
- textView.setText(doc.name());
- if(position == 0)
- Log.d("MARIANO","progressView: "+holder.progressView);
- return v;
- }
- @Override
- public Filter getFilter() {
- return new Filter() {
- @Override
- protected FilterResults performFiltering(CharSequence constraint) {
- FilterResults result = new FilterResults();
- if (constraint.equals(DocumentPickerGridViewController.FILTER_DOWNLOADED)) {
- ArrayList items = new ArrayList();
- synchronized (this) {
- items.addAll(values);
- }
- for (int i = items.size() - 1; i >= 0; i--) {
- if (((Document) items.get(i)).state() != DocumentStates.Downloaded)
- items.remove(i);
- }
- result.count = items.size();
- result.values = items;
- } else { // ALL ITEMS
- synchronized (this) {
- result.count = values.size();
- result.values = values;
- }
- }
- return result;
- }
- @SuppressWarnings("unchecked")
- @Override
- protected void publishResults(CharSequence constraint,FilterResults results) {
- filtered = (ArrayList)results.values;
- DocumentPickerGridViewAdapter.this.notifyDataSetChanged();
- clear();
- for(int i = 0,l = filtered.size(); i < l; i++)
- add((Document)filtered.get(i));
- notifyDataSetInvalidated();
- }
- };
- }
- static class ViewHolder{
- ImageView coverView;
- Button actionView;
- Button archiveButton;
- ProgressView progressView;
- ProgressBar progressBar;
- int position;
- Document doc;
- }
- }
网格视图 :
- <com.kaldorgroup.newsweek.ExpandableGridView
- android:id="@+id/documentPickerGridView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:columnWidth="150dp"
- android:numColumns="auto_fit"
- android:horizontalSpacing="25dp"
- android:stretchMode="spacingWidth"
- android:verticalSpacing="20dp"
- android:layout_marginTop="10dp"
- android:layout_marginBottom="5dp"
- android:layout_marginLeft="15dp"
- android:layout_marginRight="15dp"
- android:isScrollContainer="false"
- android:paddingTop="350dp" />
解决方法
我在GridView中遇到了完全相同的问题.在单击列表的第一项时,它不会刷新.我只是改变了代码
- public View getView(int position,ViewGroup parent)
- {
- View v = convertView;
- if (convertView == null)
- {
- LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- v = vi.inflate(R.layout.calendar_item,null);
- }
- .......
- }
- to
- public View getView(int position,ViewGroup parent)
- {
- View v = convertView;
- // if (convertView == null)
- // {
- LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- v = vi.inflate(R.layout.calendar_item,null);
- // }
- .......
- }
- It is working fine to me.. But I don't have idea how it happens...
- Any Clarification on this will be more helpful!!