ListView正在混合条目

时间:2015-02-24 09:07:57

标签: android

我有一个奇怪的问题,我无法弄清楚问题是什么。我有以下简单的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/measuredata_list_row_parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginEnd="20dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:divider="@null"
        android:dividerHeight="5dp"
        android:listSelector="@android:color/transparent"
        android:textColor="@color/textcolorprimary" />

</LinearLayout>

我使用的适配器如下:

public class MeasureDataListAdapter extends ArrayAdapter<MeasureDataListEntry> {

    public MeasureDataListAdapter(Context context, List<MeasureDataListEntry> entries) {
        super(context, R.layout.activity_measuredata_list_fragment_row, entries);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final MeasureDataListEntry entry = this.getItem(position);

        ViewHolder viewHolder = null;
        LayoutInflater inflater = null;

        if(convertView == null) {
            inflater = LayoutInflater.from(this.getContext());
            convertView = inflater.inflate(R.layout.activity_measuredata_list_fragment_row, parent, false);

            viewHolder = new ViewHolder();
            viewHolder.textViewTime = (TextView) convertView.findViewById(R.id.measuredata_list_row_textview_time);
            viewHolder.textViewValue = (TextView) convertView.findViewById(R.id.measuredata_list_row_textview_value);
            viewHolder.textViewMood = (TextView) convertView.findViewById(R.id.measuredata_list_row_textview_mood);
            viewHolder.layoutMealTime = (LinearLayout) convertView.findViewById(R.id.measuredata_list_row_layout_mealtime);
            viewHolder.textViewMealTime = (TextView) convertView.findViewById(R.id.measuredata_list_row_textview_mealtime);
            viewHolder.imageButtonMeal = (ImageButton) convertView.findViewById(R.id.measuredata_list_row_imagebutton_meal);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.textViewTime.setText(Helper.getDateTimePattern(this.getContext(), entry.getTime()));
        viewHolder.textViewValue.setText(entry.getValue() + " " + Helper.getUnitForShortcut(this.getContext(), entry.getUnit()));
        viewHolder.textViewMood.setText(Helper.getMood(this.getContext(), entry.getMood()));

        String mealTime = Helper.getMealTimeForShortcut(this.getContext(), entry.getMealTime());

        if(mealTime != null && !mealTime.trim().isEmpty()) {
            viewHolder.layoutMealTime.setVisibility(LinearLayout.VISIBLE);
            viewHolder.textViewMealTime.setText(mealTime);
        }

        File imageFile = entry.getImageFile();

        if(imageFile != null) {
            viewHolder.imageButtonMeal.setVisibility(ImageButton.VISIBLE);
        }

        return convertView;
    }

    private static class ViewHolder {
        private TextView textViewTime = null;
        private TextView textViewValue = null;
        private TextView textViewMood = null;
        private LinearLayout layoutMealTime = null;
        private TextView textViewMealTime = null;
        private ImageButton imageButtonMeal = null;
    }
}

这是List的Fragment

public class MeasureDataListFragment extends DiagramBaseFragment implements OnDateSetListener, MeasureDataGetCallback {
    private MeasureDataListAdapter measureDataListAdapter = null;
    private ListView listRowParent = null;
    private List<MeasureDataListEntry> measureDataListEntries = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.setRetainInstance(true);
        this.setHasOptionsMenu(true);

        this.sessionLoginPreferences = new SessionLoginPreferences(this.getActivity());
        this.sessionLoginSingleton = SessionLoginSingleton.getInstance(this.getActivity());
        this.sessionProfilePreferences = new SessionProfilePreferences(this.getActivity());
        this.sessionMeasureDataPreferences = new SessionMeasureDataPreferences(this.getActivity());
        this.sessionMeasureDataListSingleton = SessionMeasureDataListSingleton.getInstance();
        this.sessionMeasureDataListFavouriteSingleton = SessionMeasureDataListFavouriteSingleton.getInstance();

        if(this.sessionMeasureDataListSingleton.getMeasureDataList() == null) {
            this.sessionMeasureDataListSingleton.setMeasureDataList(new MeasureDataList());
        }

        if(this.sessionMeasureDataListFavouriteSingleton.getMeasureDataList() == null) {
            this.sessionMeasureDataListFavouriteSingleton.setMeasureDataList(new MeasureDataList());
        }

        this.measureDataListEntries = new ArrayList<MeasureDataListEntry>();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.activity_measuredata_list_fragment, container, false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        this.measureDataListAdapter = new MeasureDataListAdapter(this.getActivity(), this.measureDataListEntries);

        this.listRowParent = (ListView) view.findViewById(R.id.measuredata_list_row_parent);
        this.listRowParent.setAdapter(this.measureDataListAdapter);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);

        if((this.sessionMeasureDataListFavouriteSingleton != null || this.sessionMeasureDataListSingleton != null)) {
            this.fragmentBecameVisible();
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.diagram_activity_actions, menu);

        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            this.getActivity().finish();
            return true;
        case R.id.action_search:
            this.showDatePicker(this.getResources().getString(R.string.text_from));
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        monthOfYear = (monthOfYear + 1);

        if(view == null && year == 0 && monthOfYear == 0 && dayOfMonth == 0) {
            this.from = true;
        } else {
            if(from) {
                this.fromDate = dayOfMonth + "." + monthOfYear + "." + year;
                this.from = false;

                this.showDatePicker(this.getResources().getString(R.string.text_to));
            } else {
                this.toDate = dayOfMonth + "." + monthOfYear + "." + year;
                this.from = true;

                this.getMeasureData(this.fromDate, this.toDate);
            }
        }
    }

    @Override
    public void onMeasureDataGetCompleted(StatusMeasureDataGet status, MeasureDataGetPOJO measureDataGetPOJO) {
        switch(status) {
            case MEASUREDATA_TRANSFERED: {
                if(this.favourite) {
                    this.sessionMeasureDataListFavouriteSingleton.setMeasureDataList(measureDataGetPOJO);
                } else {
                    this.sessionMeasureDataListSingleton.setMeasureDataList(measureDataGetPOJO);
                    this.saveLastMeasureData();
                }

                this.fragmentBecameVisible();
            } break;
            case ERROR_CONNECTION_FAILED: {
                String title = this.getResources().getString(R.string.text_error);
                String message = this.getResources().getString(R.string.text_connection_failed);

                DialogManager.showAlertDialog(title, message, this.getFragmentManager());
            } break;
            case ERROR_IO_EXCEPTION: {
                String title = this.getResources().getString(R.string.text_error);
                String message = this.getResources().getString(R.string.text_io_exception);

                DialogManager.showAlertDialog(title, message, this.getFragmentManager());
            } break;
            case ERROR_JSON_EXCEPTION: {
                String title = this.getResources().getString(R.string.text_error);
                String message = this.getResources().getString(R.string.text_json_exception);

                DialogManager.showAlertDialog(title, message, this.getFragmentManager());
            } break;
            case ERROR_NO_DATA_FOUND: {
                String title = this.getResources().getString(R.string.text_error);
                String message = this.getResources().getString(R.string.text_not_data_found);

                DialogManager.showAlertDialog(title, message, this.getFragmentManager());
            } break;
            case ERROR_PROTOCOL_EXCEPTION: {
                String title = this.getResources().getString(R.string.text_error);
                String message = this.getResources().getString(R.string.text_protocol_exception);

                DialogManager.showAlertDialog(title, message, this.getFragmentManager());
            } break;
            case ERROR_WRONG_PARAMETERS: {
                String title = this.getResources().getString(R.string.text_error);
                String message = this.getResources().getString(R.string.text_wrong_parameters);

                DialogManager.showAlertDialog(title, message, this.getFragmentManager());
            } break;
            case ERROR_WRONG_USER_OR_PW: {
                String title = this.getResources().getString(R.string.text_input_error);
                String message = this.getResources().getString(R.string.text_wrong_mail_or_pw);

                DialogManager.showAlertDialog(title, message, this.getFragmentManager());
            } break;
        }
    }

    private void fragmentBecameVisible() {
        this.initAdapter();

        if(this.measureDataListAdapter != null) {
            this.measureDataListAdapter.notifyDataSetChanged();
        }
    }

    /**
     * 
     */
    protected void initAdapter() {
        this.measureDataListEntries.clear();

        if(this.favourite) {
            measureDataList = this.sessionMeasureDataListFavouriteSingleton.getMeasureDataList();
        } else {
            measureDataList = this.sessionMeasureDataListSingleton.getMeasureDataList();
        }

        Collections.sort(measureDataList.getMeasureDataListEntries());

        for(MeasureDataListEntry measureDataListEntry : measureDataList.getMeasureDataListEntries()) {
            this.measureDataListEntries.add(measureDataListEntry);
        }
    }

    protected void saveLastMeasureData() {
        String email = this.getEmail();

        MeasureDataListEntry measureData = this.sessionMeasureDataPreferences.getMeasureData(this.getEmail());

        int index = (this.sessionMeasureDataListSingleton.getMeasureDataList().getMeasureDataListEntries().size() - 1);

        MeasureDataListEntry measureDataListEntry = this.sessionMeasureDataListSingleton.getMeasureDataList().getMeasureDataListEntries().get(index);

        if(measureDataListEntry.compareTo(measureData) > 0) {
            this.sessionMeasureDataPreferences.setMeasureData(email, measureDataListEntry);
        }
    }

    protected void getMeasureData(final String fromDate, final String toDate) {
        String email = this.getEmail();
        String password = this.getPassword();

        FragmentTransaction fragmentTransaction = this.getFragmentManager().beginTransaction();
        MeasureDataGetTask measureDataGetTask = new MeasureDataGetTask(email, password, fromDate, toDate);
        MeasureDataGetDialogFragment measureDataGetDialogFragment = new MeasureDataGetDialogFragment(measureDataGetTask, this);

        measureDataGetDialogFragment.show(fragmentTransaction, null);
    }

    protected void showDatePicker(String title) {
        FragmentTransaction fragmentTransaction = this.getFragmentManager().beginTransaction();
        DatePickerDialogFragment datePickerDialogFragment = new DatePickerDialogFragment(this, title);

        datePickerDialogFragment.show(fragmentTransaction, null);
    }
}

现在问题

当我用数据填充列表时,一切似乎都没问题,它包含19个条目。只有列表的最后一个条目包含图像。只要我不滚动到最后一个条目与图像一切都保持不变。

但是在我用图像滚动到最后一个条目之后,数据以某种方式完全混淆了。当我现在突然再次向上滚动时,第4个第9个和第14个条目包含一个图像和完全相同的图像,如最后一个条目(两个条目不应包含相同的图像)。

所以我的问题是:滚动到带有图像的条目后,列表怎么可能被破坏?如何将最后一个条目的图像突然复制到其他条目?

2 个答案:

答案 0 :(得分:2)

您只需在else方法中添加getView()语句,如下所示:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final MeasureDataListEntry entry = this.getItem(position);
    //every thing like before...
    if(imageFile != null) {
        viewHolder.imageButtonMeal.setVisibility(ImageButton.VISIBLE);
    }else{
       viewHolder.imageButtonMeal.setVisibility(ImageButton.INVISIBLE); //or GONE
    }

    return convertView;
}  

之所以发生这种情况,是因为当您显示最后一行时VISIBLE imageView但在其他行中从未显示INVISIBLE,所以当您访问最后一行时,其可见性更改为VISIBLE并且对于其他行也是如此

答案 1 :(得分:0)

您可以尝试更改

吗?
if(imageFile != null) {
            viewHolder.imageButtonMeal.setVisibility(ImageButton.VISIBLE);
        }

if(imageFile != null) {
            viewHolder.imageButtonMeal.setVisibility(ImageButton.VISIBLE);
        }else{
           viewHolder.imageButtonMeal.setVisibility(ImageButton.GONE);
    }