滚动列表

时间:2017-05-29 00:09:52

标签: android listview duplicates android-arrayadapter

我创建了一个自定义ArrayAdapter,在ArrayAdapter中有一个LinearLayout,可以通过迭代添加视图。现在,在显示需要在ListView上显示的数据后,所有内容都会很好,直到我向下滚动或向上滚动列表,当一行经过回收并​​绑定新视图以显示在回收行上时,我得到重复,但是这些副本有重复在视图上不显示数据(文本)。这是滚动前的视图ListView

https://postimg.org/image/z36eqhacd/

这是滚动后的ListView

https://postimg.org/image/dzv28kj9t/

我尝试过多种方法,但似乎无法让它发挥作用。

public class SurveyAdapter extends ArrayAdapter<SurveyModel> {

public SurveyAdapter(Context context, ArrayList<SurveyModel> objects) {
    super(context, R.layout.survey_card, objects);
}

@NonNull
@Override
public View getView(int position, View convertView, @Nullable ViewGroup parent) {
    //Get the data item for this position
    SurveyModel surveyModel = getItem(position);

    //Construct the ViewHolder
    ViewHolder viewHolder = new ViewHolder();

    //Check if an existing view is being reused, otherwise inflate the view
    if (convertView == null) {
        //If there's no view to re-use, inflate a new view for a row
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.survey_card, parent, false);
        viewHolder.mContainer = (LinearLayout) convertView.findViewById(R.id.choice_container);
        viewHolder.question = (TextView) convertView.findViewById(R.id.question);
        //Cache the viewHolder object inside the new view
        convertView.setTag(viewHolder);
    } else {
        //View is being recycled, retrieve the viewHolder object from tag
        viewHolder = (ViewHolder) convertView.getTag();
    }

    assert surveyModel != null;

    //Populate the data from the data object
    String choices = surveyModel.getChoice();

    //Scan each string separately
    //Strings are separated with a comma ','
    Scanner scanner = new Scanner(choices).useDelimiter(",\\s*");

    //Create an array list to store each string separately
    ArrayList<String> choiceList = new ArrayList<>();

    //Get all strings from scanner separately
    while (scanner.hasNext()) {
        String choice = scanner.next(); //Get each string from scanner
        choiceList.add(choice); //Store the string in an ArrayList(choiceList)
    }

    //Convert choiceList(ArrayList) to a StringArray(choiceArray)
    String[] choiceArray = choiceList.toArray(new String[choiceList.size()]);

    int choiceNum; //Will store number of choices to be displayed
    if (choices.contains("Other,true") || choices.contains("Other,false")) {
        //Set number or choices to the length(number of items) of the choiceList(ArrayList)
        //Minus 1 to avoid showing "true" as an option
        choiceNum = choiceArray.length - 1;
    } else {
        //Set number or choices to the length(number of items) of the array
        choiceNum = choiceArray.length;
    }

    //Get number of choices from choiceNum
    final int numOfChoices = choiceNum;

    //Populate each choice string from choiceArray
    for (int i = 0; i < numOfChoices; i++) {
        //Create a new CheckBox for each choice
        AppCompatCheckBox checkBox = new AppCompatCheckBox(getContext());
        checkBox.setLayoutParams(new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        //Add the CheckBox to its survey_view_list view(mContainer)
        viewHolder.mContainer.addView(checkBox);

        if (viewHolder.mContainer.getChildAt(i) instanceof AppCompatCheckBox) {
            //Set each data item in the choiceArray on its own CheckBox according to position
            ((AppCompatCheckBox) viewHolder.mContainer.getChildAt(i)).setText(choiceArray[i]);

            final ViewHolder finalViewHolder = viewHolder; //Get viewHolder for inner class access
            final int checkBoxPosition = i; //Set position of the checked CheckBox

            ((AppCompatCheckBox) viewHolder.mContainer.getChildAt(i)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
                    if (checked) {
                        for (int i = 0; i < numOfChoices; i++) {
                            //Disable all CheckBoxes when a CheckBox is checked
                            finalViewHolder.mContainer.getChildAt(i).setEnabled(false);
                            //Re-enable the checked CheckBox only
                            finalViewHolder.mContainer.getChildAt(checkBoxPosition).setEnabled(true);
                        }
                    } else {
                        for (int i = 0; i < numOfChoices; i++) {
                            //Enable all CheckBoxes when the checked CheckBox is unchecked
                            finalViewHolder.mContainer.getChildAt(i).setEnabled(true);
                        }
                    }
                }
            });
        }
    }

    //Populate the data from the data object via the viewHolder object into the view
    viewHolder.question.setText(surveyModel.getQuestion());

    //Return the completed view to render on screen
    return convertView;
}

//View lookup cache
private static class ViewHolder {
    LinearLayout mContainer;
    TextView question;
}`

这是对象模型

public class SurveyModel {

private String question, choice;

public String getQuestion() {
    return question;
}

public void setQuestion(String question) {
    this.question = question;
}

public String getChoice() {
    return choice;
}

public void setChoice(String choice) {
    this.choice = choice;
}
}

以下是我将ArrayAdapter附加到ListView

的Activity的方法
//Method to populate and display data populated from the database
private void populateAndDisplayData() {

//Construct ArrayList
    ArrayList<SurveyModel> surveyModelArrayList = new ArrayList<>();

    //Construct adapter
    SurveyAdapter adapter = new SurveyAdapter(CreateFromScratch.this, surveyModelArrayList);

    //Attach the adapter to the ListView
    binding.list.setAdapter(adapter);

    //Create a ListView
    ListView listView = new ListView(CreateFromScratch.this);

    //Get all the data from the database
    Cursor allDataCursor = tempSurveyDatabase.fetchAllData();

    //StringArray to hold the strings from the database
    String[] from = new String[]{CustomSurveyDatabase.QUESTION, CustomSurveyDatabase.CHOICES};

    //Views to display the string data from StringArray(from)
    int[] to = new int[]{R.id.question, R.id.choices};

    //Construct a SimpleCursorAdapter
    SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(CreateFromScratch.this, R.layout.survey_card, allDataCursor, from, to);

    // /Attach the adapter to the ListView
    listView.setAdapter(simpleCursorAdapter);

    //Construct StringBuilder
    StringBuilder jsonBuilder = new StringBuilder();

    //Strings to hold the item's data from the database
    String question = null;
    String choices = null;

    //Proceed with collecting each item's data if the SimpleCursorAdapter is not empty
    if (simpleCursorAdapter.getCount() > 0) {
        //Get every item's id from the database
        for (int i = 0; i < simpleCursorAdapter.getCount(); i++) {

            //Get each item's database id
            long itemId = listView.getAdapter().getItemId(i);

            //Get each item from the database
            try {
                //Construct cursor to fetch an item's data from the database
                Cursor cursor = tempSurveyDatabase.fetchItem(itemId);
                question = tempSurveyDatabase.questionHolder;
                choices = tempSurveyDatabase.choiceHolder;
            } catch (SQLException e) {
                Log.v(TAG, e.getMessage());
            }

            if (i == 0) {
                jsonBuilder.append("{\"survey\": [").append("{\"question\":\"").append(question).append("\",");
                jsonBuilder.append("\"choices\":\"").append(choices).append("\"},");
            } else {
                jsonBuilder.append("{\"question\":\"").append(question).append("\",");
                jsonBuilder.append("\"choices\":\"").append(choices).append("\"},");
            }
        }

        //Remove the last comma from the StringBuilder
        jsonBuilder.deleteCharAt(jsonBuilder.length() - 1);
        //Close JSON file scopes
        jsonBuilder.append("]}");

        //Save temporary survey file on the SDCARD
        try {
            //Delete existing temporary survey
            if (TEMP_SURVEY.exists()) {
                //noinspection ResultOfMethodCallIgnored
                TEMP_SURVEY.delete();
            }
            FileWriter fileWriter = new FileWriter(TEMP_SURVEY);
            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
            bufferedWriter.write(String.valueOf(jsonBuilder));
            bufferedWriter.close();
        } catch (IOException e) {
            Log.v(TAG, "Temp Survey JSON file failed to write.\nReason: " + e.getMessage());
        }

        //Check if the temporary survey file exists
        if (TEMP_SURVEY.exists()) {
            //Read the temporary survey file if it exists
            new ReadFile(ReadFile.data, ReadFile.output, TEMP_SURVEY);
            //Parse JSON string from StringBuilder
            try {
                JSONObject jsonObjectMain = new JSONObject(ReadFile.output);
                JSONArray jsonArray = jsonObjectMain.getJSONArray(SurveyJSONKeys.ARRAY_KEY);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    SurveyModel surveyModel = new SurveyModel();
                    surveyModel.setQuestion(jsonObject.getString(SurveyJSONKeys.QUESTION_KEY));
                    surveyModel.setChoice(jsonObject.getString(SurveyJSONKeys.CHOICES_KEY));
                    surveyModelArrayList.add(surveyModel);
                }
            } catch (JSONException e) {
                Log.v(TAG, "Unable to parse JSON file.\nReason: " + e.getMessage());
            }
            //Notify the adapter for changes in order to refresh views
            adapter.notifyDataSetChanged();
        }
    }
}`

1 个答案:

答案 0 :(得分:0)

由于您的项目视图每次都会被回收,因此您的答案容器只会附加更多答案。您有两个选择:

  1. 在填充答案之前删除容器中的所有子视图
  2. 请勿使用Public Sub Create_Outlook_Email() Dim OutApp As Object, OutMail As Object, OutWordEditor As Object Dim WordDoc As Object Dim wordfile As String Dim rng As Range Dim row As Range Dim cell As Range 'Create new Outlook email Set rng = Range("a2:a50") Set OutApp = CreateObject("Outlook.Application") Set OutMail = OutApp.CreateItem(0) Set OutWordEditor = OutMail.GetInspector.WordEditor For Each row In rng.Rows For Each cell In row.Cells With OutMail .To = cell.Value .Subject = "Your emails are moving on " & Range("e2").Value & "- don't get left behind " wordfile = Application.GetOpenFilename(Title:="Select MS Word file", MultiSelect:=False) Set WordDoc = GetObject(wordfile) WordDoc.Content.Copy WordDoc.Close OutWordEditor.Content.Paste 'See if Outlook is using Word to edit messages .display .send End With Set OutApp = Nothing Set OutMail = Nothing Set OutWordEditor = Nothing Set WordDoc = Nothing Next cell Next row End Sub getViewTypeCount()强制回收。