RecyclerView仅显示List中的最后一个对象

时间:2017-07-25 17:42:17

标签: android android-recyclerview recycler-adapter

我正在尝试在RecyclerView中显示数据。我已经创建了一个适配器来处理来自不同活动的RecyclerView。我面临的问题是适当地显示数据。到目前为止,我只能显示列表中的最后一个元素。在这种情况下,每个ContestedOffice的最后一个候选人。我已经为活动和适配器附加了我的代码以及输出的屏幕截图。

我的适配器类

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final String LOGCAT = RecyclerAdapter.class.getSimpleName();
    private static final int VIEW_TYPE_VOTE = 0;
    private static final int VIEW_TYPE_PREVIEW = 1;
    private List candidatesList;
    private LinearLayout checkBoxParent;
    private VoteActivity voteActivity;
    private Context context;

    public RecyclerAdapter(List candidatesList) //Generic List
    {
        this.candidatesList = candidatesList;
    }

    @Override
    public int getItemViewType(int position) {
        if (candidatesList.get(position) instanceof Candidate) {
            return VIEW_TYPE_PREVIEW;
        } else {
            return VIEW_TYPE_VOTE;
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        context = parent.getContext();

        if (viewType == VIEW_TYPE_PREVIEW) {
            View preview = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_candidate_recycler, parent, false);
            return new CandidateViewHolder(preview); // view holder for candidates items
        } else if (viewType == VIEW_TYPE_VOTE) {
            View ballot = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_ballot_view, parent, false); //false too
            return new BallotViewHolder(ballot); // view holder for ContestedOffice items
        }
        return null;
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
        final int itemType = getItemViewType(position);

        if (itemType == VIEW_TYPE_PREVIEW) {
            CandidateViewHolder.class.cast(holder).bindData((Candidate)
                    candidatesList.get(position));

        } else if (itemType == VIEW_TYPE_VOTE) {
            BallotViewHolder.class.cast(holder).bindData((ContestedOffice)
                    candidatesList.get(position));
        }
    }

    @Override
    public int getItemCount() {
        Log.d(LOGCAT, " Size: " + candidatesList.size());
        return candidatesList.size();
    }

    /**
     * ViewHolder class
     */
    private class BallotViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private AppCompatTextView vote_candidate_name;
        private AppCompatTextView vote_candidate_details;
        private AppCompatTextView vote_candidate_party;
        BallotViewHolder(View view) {
            super(view);

            checkBoxParent = (LinearLayout) view.findViewById(R.id.checkbox_layout_parent);
            vote_candidate_name = (AppCompatTextView) view.findViewById(R.id.vote_candidate_name)
            vote_candidate_party = (AppCompatTextView) view.findViewById(R.id.vote_candidate_party);
            vote_candidate_details = (AppCompatTextView) view.findViewById(R.id.vote_candidate_details);
        }

        void bindData(ContestedOffice candidate)
        {
            int length = candidate.getList().size();

            Log.d(LOGCAT, "BallotList size:" + length);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    RecyclerView.LayoutParams.WRAP_CONTENT, RecyclerView.LayoutParams.WRAP_CONTENT);
            //params.setMargins(10, 10, 10, 10);
            params.gravity = Gravity.END;

            CheckBox checkBox = null;
            for (int i = 0; i < length; i++)
            {
                vote_candidate_name.setText(candidate.getList().get(i).getCandidateName());
                vote_candidate_party.setText(candidate.getList().get(i).getParty());
                vote_candidate_details.setText(candidate.getList().get(i).getDetails());

                //Create checkboxes for each recycler view created
                checkBox = new CheckBox(context);
                checkBox.setTag(candidate.getList().get(i).getCandidateID());
                checkBox.setId(candidate.getList().get(i).getCandidateID());
                //checkBox.setText(R.string.checkBox_message);
                checkBox.setText(String.valueOf(candidate.getList().get(i).getCandidateID()));
                checkBox.setBackgroundColor(Color.RED);
                Log.d(LOGCAT, "TAGS: " + checkBox.getTag() + " id: " + checkBox.getId());
            }
            if (checkBox != null) {
                checkBox.setOnClickListener(this);
            }
            checkBoxParent.addView(checkBox, params);
        }

        @Override
        public void onClick(View v) {
            // Is the view now checked?
            boolean checked = ((CheckBox) v).isChecked();

            // Check which checkbox was clicked
            switch (v.getId()) {
                case 31:
                    if (checked) {
                        Log.d(LOGCAT, "Here:" + v.getTag().toString());
                    } else

                        break;
                case 30:
                    if (checked) {
                        Log.d(LOGCAT, "Here:" + v.getTag().toString());
                    } else

                        break;
            }
        }
    }

    /**
     * ViewHolder class
     */
    private class CandidateViewHolder extends RecyclerView.ViewHolder {

        private AppCompatTextView candidate_name;
        private AppCompatTextView candidate_details;
        private AppCompatTextView candidate_party;
        private AppCompatTextView candidate_position;
        // private AppCompatImageView candidate_image;

        CandidateViewHolder(View view) {
            super(view);

            candidate_name = (AppCompatTextView) view.findViewById(R.id.candidate_name);
            //  candidate_image = (AppCompatImageView) view.findViewById(R.id.candidate_image);
            candidate_position = (AppCompatTextView) view.findViewById(R.id.candidate_position);
            candidate_party = (AppCompatTextView) view.findViewById(R.id.candidate_party);
            candidate_details = (AppCompatTextView) view.findViewById(R.id.candidate_details);
        }

        void bindData(Candidate candidate)//Candidate
        {
            candidate_name.setText(candidate.getCandidateName());
            candidate_position.setText(candidate.getPosition());
            candidate_details.setText(candidate.getDetails());
            candidate_party.setText(candidate.getParty());
            // candidate_image.setImageBitmap(candidate.getCandidatePhoto());
        }

    }
}

我的VoteActivity Class

public class VoteActivity extends AppCompatActivity implements View.OnClickListener
{
    private static final String LOGCAT = VoteActivity.class.getSimpleName();

    private AppCompatActivity activity = VoteActivity.this;

    private RecyclerView vote_recycler_view;
    private LinearLayout checkBoxParent;

    private CheckBox vote_candidate_checkBox;

    private AppCompatButton appCompatButtonVote;

    private RecyclerAdapter recyclerAdapter;

    RecyclerView.LayoutManager layoutManager;

    private Ballot ballot;

    private List <ContestedOffice> ballotList = new ArrayList<>();
    private List<Candidate> candidateList = new ArrayList<>();
    private DatabaseHelper databaseHelper;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vote);
        getSupportActionBar().setTitle("");

        initViews();
        initObjects();
        initListeners();
    }

    private void initListeners()
    {
        appCompatButtonVote.setOnClickListener(this);
    }

    private void initObjects()
    {
        recyclerAdapter = new RecyclerAdapter(ballotList);
        databaseHelper = new DatabaseHelper(this);

        layoutManager = new LinearLayoutManager(activity);
        vote_recycler_view.setLayoutManager(layoutManager);
        vote_recycler_view.setItemAnimator(new DefaultItemAnimator());
        vote_recycler_view.setHasFixedSize(true);
        vote_recycler_view.setAdapter(recyclerAdapter);
        getCandidates();
    }

    private void getCandidates()
    {
        new AsyncTask<Void, Void, Void>()
        {
            @Override
            protected Void doInBackground(Void... params)
            {
                ballotList.clear();
                candidateList.clear();
                candidateList.addAll(databaseHelper.getAllCandidates());
                createBallot();
                return null;
            }
            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);
                                    recyclerAdapter.notifyDataSetChanged();
            }
        }.execute();
    }

    private void initViews()
    {
        checkBoxParent = (LinearLayout) findViewById(R.id.checkbox_layout_parent);
        vote_recycler_view = (RecyclerView) findViewById(R.id.vote_recycler_view);
        //vote_candidate_checkBox = (CheckBox) findViewById(R.id.vote_candidate_checkBox);
        appCompatButtonVote = (AppCompatButton) findViewById(R.id.appCompatButtonVote);
    }

    public List<ContestedOffice> createBallot()
    {
        int candidateListSize = candidateList.size();
        String position;

        ArrayList<String> positionArray = new ArrayList<>();

        ContestedOffice office;

        //Looping through the candidates list and add all the positions being contested for
        // to an array list.
        for (int i = 0; i< candidateListSize; i++)
        {
            position = candidateList.get(i).getPosition();

            positionArray.add(position);
        }

        //Create a set to remove all duplicate positions
        Set<String> noDuplicates = new HashSet<>();
        noDuplicates.addAll(positionArray);
        positionArray.clear();
        positionArray.addAll(noDuplicates);

        Log.d(LOGCAT, "Contested Offices and Candidates: " + positionArray.size() + " "+ candidateListSize);

        //Create the Contested Office according to the size of the position array
        //and make sure the names are added.
        int noOfContestedOffice = positionArray.size();

        for(int i = 0; i<noOfContestedOffice; i++)
        {
            office = new ContestedOffice(positionArray.get(i));
            Log.d(LOGCAT, "New Contested Office Created:" + office.getName());

            Candidate c = new Candidate();
            for(int j = 0; j < candidateListSize; j++)
            {
                //All the Seats/Position being Contested For
                String candidatePosition = candidateList.get(j).getPosition();
                String contestedOfficeName = office.getName();

                if(candidatePosition.equals(contestedOfficeName)) {
                    c = candidateList.get(j);
                    //Add the candidate to the Contested Office
                    office.add(c);
                }
                Log.d(LOGCAT, "Added Candidate: "+ candidateList.get(j) +" to: "+ office.getName());
            }
            //Add offices to ballot and ballot List
            ballot = new Ballot();
            ballot.add(office);

            //Ideally Ballot into BallotList
            ballotList.add(office);
            Log.d(LOGCAT, "Office definitely added to ballotList: " + ballotList.size());
        }
        return ballotList;
    }
}

我的VoteActivity XML

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="@color/colorBackground"
    android:orientation="vertical"
    tools:context=".activities.VoteActivity">

    <android.support.v7.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:orientation="vertical">

        <android.support.v7.widget.AppCompatTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/dashboard_vote_message"
            android:textAlignment="center"
            android:textSize="20sp" />

        <android.support.v7.widget.AppCompatTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:textAlignment="center"
            android:id="@+id/vote_message_placeholder"
            android:text="@string/vote_message" />
    </android.support.v7.widget.LinearLayoutCompat>

    <include layout="@layout/fragment_ballot_layout"/>

    <include layout="@layout/footer_vote_button" />

</LinearLayout>

RecyclerView XML

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

<LinearLayout
    android:id="@+id/recycler_layout_parent"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_marginTop="5dp">

        <android.support.v7.widget.RecyclerView
            android:layout_weight="1"
            android:id="@+id/vote_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"/>
    </LinearLayout>

</LinearLayout>

CardView XML

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        xmlns:tools="http://schemas.android.com/tools"
        card_view:cardCornerRadius="4dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="?android:attr/listPreferredItemHeight"
            android:orientation="horizontal">

            <android.support.v7.widget.AppCompatImageView
                android:id="@+id/vote_candidate_image"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_gravity="center_vertical"
                android:fontFamily="sans-serif-medium"
                android:gravity="center"
                android:src = "@drawable/btn_ballot"
                android:textColor="@android:color/white"
                android:textSize="16sp"
                tools:text="8.9"
                android:contentDescription="@string/candidate_photo" />

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="16dp"
                android:layout_marginStart="16dp"
                android:layout_weight="1"
                android:orientation="vertical">

                <android.support.v7.widget.AppCompatTextView
                    android:id="@+id/vote_candidate_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ellipsize="end"
                    android:fontFamily="sans-serif-medium"
                    android:maxLines="1"
                    android:textAllCaps="true"
                    android:textColor="@color/textColorCandidateName"
                    android:textSize="12sp"
                    tools:text="CANDIDATE NAME" />

                <android.support.v7.widget.AppCompatTextView
                    android:id="@+id/vote_candidate_party"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/textColorPartyDetails"
                    android:textSize="12sp"
                    android:ellipsize="end"
                    tools:text="PARTY NAME" />

                <android.support.v7.widget.AppCompatTextView
                    android:id="@+id/vote_candidate_details"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:ellipsize="end"
                    android:maxLines="2"
                    android:textColor="@color/textColorDetails"
                    android:textSize="16sp"
                    tools:text="Long placeholder for candidate details. 2 Lines Max" />

            </LinearLayout>

            <LinearLayout
                android:id="@+id/checkbox_layout_parent"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="16dp"
                android:layout_marginStart="16dp"
                android:orientation="vertical">

                <!--Dynamic Checkboxes here-->

            </LinearLayout>
        </LinearLayout>

    </android.support.v7.widget.CardView>

Code Output

1 个答案:

答案 0 :(得分:0)

我认为你每次都在创建候选人的对象,因为它会解决你的问题,它会解决你的问题

 Candidate c = new Candidate();
 ballot = new Ballot();
for(int i = 0; i<noOfContestedOffice; i++)
        {
            office = new ContestedOffice(positionArray.get(i));
            Log.d(LOGCAT, "New Contested Office Created:" + office.getName());


            for(int j = 0; j < candidateListSize; j++)
            {
                //All the Seats/Position being Contested For
                String candidatePosition = candidateList.get(j).getPosition();
                String contestedOfficeName = office.getName();

                if(candidatePosition.equals(contestedOfficeName)) {
                    c = candidateList.get(j);
                    //Add the candidate to the Contested Office
                    office.add(c);
                }
                Log.d(LOGCAT, "Added Candidate: "+ candidateList.get(j) +" to: "+ office.getName());
            }
            //Add offices to ballot and ballot List

            ballot.add(office);

            //Ideally Ballot into BallotList
            ballotList.add(office);
            Log.d(LOGCAT, "Office definitely added to ballotList: " + ballotList.size());
        }

只需检查一次即可解决问题。

我在

下面更新了xml
 <android.support.v7.widget.RecyclerView
            android:layout_weight="1"
            android:id="@+id/vote_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>

检查一下Recyclerview的高度。