单击时,回收器视图项的高度会意外更改

时间:2017-08-02 21:08:12

标签: android android-recyclerview

我有一个带有搜索视图和回收站视图的片段,您可以使用该视图一次选择一个项目(所选项目将突出显示)。项目高度可能因所显示的内容而异。单击回收器视图项时,我将更改该项的背景颜色,然后将所选项存储到变量中供以后使用。但是,当选择项目时,它的高度也会发生显着变化。它的项目细节正在被无意中折叠或扩展(似乎并非如此)。

我不太确定,但我认为它与细胞的重复使用有关。我刚开始研究android时,我无法弄清楚确切的问题。

如果需要,这是显示问题的link to the video

我该如何解决这个问题?

我的适配器类是 -

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

    private List<Code> codes;
    private Code selectedCode;
    private int selectedPosition = -1;

    public CodeListAdapter(Code selectedCode) {
        this.selectedCode = selectedCode;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_code, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Code code = codes.get(position);
        holder.codeIdentifier.setText(code.getCodeIdentifier());

        if (code.getCodeType() == null || code.getCodeType().isEmpty()) {
            holder.codeType.setVisibility(View.GONE);
        } else {
            holder.codeType.setText(code.getCodeType());
        }

        if (code.getCodeDescription() == null || code.getCodeDescription().isEmpty()) {
            holder.codeDescription.setVisibility(View.GONE);
        } else {
            holder.codeDescription.setText(code.getCodeDescription());
        }

        if (selectedCode == code) {
            holder.itemLayout.setBackgroundResource(R.color.colorEmphasis);
        } else {
            holder.itemLayout.setBackgroundResource(R.color.colorWhite);
        }

        final ViewHolder viewHolder = holder;
        holder.itemLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View itemView) {
                int currentPosition = viewHolder.getAdapterPosition();
                if (currentPosition != selectedPosition) {
                    selectedCode = codes.get(currentPosition);
                    notifyItemChanged(selectedPosition);
                    selectedPosition = currentPosition;
                    notifyItemChanged(selectedPosition);
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return codes.size();
    }

    public void setCodes(List<Code> codes) {
        this.codes = codes;
    }

    public Code getCode() {
        return selectedCode;
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        View itemLayout;
        TextView codeIdentifier;
        TextView codeType;
        TextView codeDescription;

        ViewHolder(View view) {
            super(view);
            itemLayout = view.findViewById(R.id.item_layout);
            codeIdentifier = (TextView) view.findViewById(R.id.codeIdentifier);
            codeType = (TextView) view.findViewById(R.id.codeType);
            codeDescription = (TextView) view.findViewById(R.id.codeDescription);
        }
    }
}

项目的布局文件是 -

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/black75PercentColor"
    android:paddingBottom="1dp">

    <RelativeLayout
        android:id="@+id/item_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:paddingBottom="6dp"
        android:paddingEnd="12dp"
        android:paddingStart="12dp"
        android:paddingTop="6dp">

        <TextView
            android:id="@+id/codeIdentifier"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true" />

        <TextView
            android:id="@+id/codeType"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/codeIdentifier" />

        <TextView
            android:id="@+id/codeDescription"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/codeType" />
    </RelativeLayout>
</FrameLayout>

布局文件是 -

<?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="wrap_content"
    android:orientation="vertical">

    <SearchView
        android:id="@+id/searchView"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:queryHint="@string/key_search_code" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/colorPrimary"
        android:paddingEnd="12dp"
        android:paddingStart="12dp">

        <TextView
            android:id="@+id/headerTextView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:text="Codes"
            android:textColor="@color/white"
            android:textSize="20sp" />

    </RelativeLayout>

    <mdbilling.ca.mdbilling_android.Customs.ExtendedRecyclerView
        android:id="@+id/diagnosticCodeRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <RelativeLayout
        android:id="@android:id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:paddingEnd="12dp"
        android:paddingStart="12dp">

        <TextView
            android:id="@+id/messageHeader"
            style="?android:attr/textAppearanceLarge"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAlignment="center" />

        <TextView
            android:id="@+id/messageBody"
            style="?android:attr/textAppearanceMedium"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/messageHeader"
            android:layout_marginTop="6dp"
            android:textAlignment="center" />
    </RelativeLayout>

</LinearLayout>

Customs.ExtendedRecyclerView 这里只是一个Recycler视图的扩展名(from this gist),只要适配器中的数据集为空,它就能显示@android:id/empty视图。< / p>

我做错了什么或它是这样的?

3 个答案:

答案 0 :(得分:4)

我已经测试了您的代码。我将分享录制的视频和源代码。可以帮助您找到问题。

MainActivity:

package info.androidhive.recyclerview;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private List<Movie> movieList = new ArrayList<>();
    private RecyclerView recyclerView;
    private MoviesAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

        mAdapter = new MoviesAdapter(movieList);

        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);

        recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, int position) {
                Movie movie = movieList.get(position);
                Toast.makeText(getApplicationContext(), movie.getTitle() + " is selected!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLongClick(View view, int position) {

            }
        }));

        prepareMovieData();
    }

    private void prepareMovieData() {
        Movie movie = new Movie("Mad Max: Fury Road", "Action & Adventure", "2015");
        movieList.add(movie);

        movie = new Movie("Inside Out", "Animation, Kids & Family", "2015");
        movieList.add(movie);

        movie = new Movie("Star Wars: Episode VII - The Force Awakens", "Action", "2015");
        movieList.add(movie);

        movie = new Movie("Shaun the Sheep", "Animation", "2015");
        movieList.add(movie);

        movie = new Movie("The Martian", "Science Fiction & Fantasy", "2015");
        movieList.add(movie);

        movie = new Movie("Mission: Impossible Rogue Nation", "Action", "2015");
        movieList.add(movie);

        movie = new Movie("Up", "Animation", "2009");
        movieList.add(movie);

        movie = new Movie("Star Trek", "Science Fiction", "2009");
        movieList.add(movie);

        movie = new Movie("The LEGO Movie", "Animation", "2014");
        movieList.add(movie);

        movie = new Movie("Iron Man", "Action & Adventure", "2008");
        movieList.add(movie);

        movie = new Movie("Aliens", "Science Fiction", "1986");
        movieList.add(movie);

        movie = new Movie("Chicken Run", "Animation", "2000");
        movieList.add(movie);

        movie = new Movie("Back to the Future", "Science Fiction", "1985");
        movieList.add(movie);

        movie = new Movie("Raiders of the Lost Ark", "Action & Adventure", "1981");
        movieList.add(movie);

        movie = new Movie("Goldfinger", "Action & Adventure", "1965");
        movieList.add(movie);

        movie = new Movie("Guardians of the Galaxy", "Science Fiction & Fantasy", "2014");
        movieList.add(movie);

        mAdapter.notifyDataSetChanged();
    }

}

适配器:

package info.androidhive.recyclerview;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {

    private List<Movie> moviesList;
    private Movie selectedMovie;
    private int lastSelectedPosition = -1;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title, year, genre, desc;

        public MyViewHolder(View view) {
            super(view);
            title = (TextView) view.findViewById(R.id.title);
            genre = (TextView) view.findViewById(R.id.genre);
            year = (TextView) view.findViewById(R.id.year);
            desc = (TextView) view.findViewById(R.id.desc);
        }
    }


    public MoviesAdapter(List<Movie> moviesList) {
        this.moviesList = moviesList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.movie_list_row, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Movie movie = moviesList.get(position);
        holder.title.setText(movie.getTitle());
        holder.genre.setText(movie.getGenre());
        holder.year.setText(movie.getYear());
        holder.desc.setText(movie.getGenre() + movie.getGenre() + movie.getGenre() + movie.getGenre() + movie.getGenre() + movie.getGenre() + movie.getGenre());

        if (selectedMovie == movie) {
            holder.itemView.setBackgroundResource(R.color.colorEmphasis);
        } else {
            holder.itemView.setBackgroundResource(R.color.colorWhite);
        }

        final RecyclerView.ViewHolder viewHolder = holder;
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View itemView) {
                int currentPosition = viewHolder.getAdapterPosition();
                if (currentPosition != lastSelectedPosition) {
                    selectedMovie = moviesList.get(currentPosition);
                    notifyItemChanged(lastSelectedPosition);
                    lastSelectedPosition = currentPosition;
                    notifyItemChanged(lastSelectedPosition);
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return moviesList.size();
    }
}

行布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusable="true"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:clickable="true"
    android:background="?android:attr/selectableItemBackground"
    android:orientation="vertical">

    <TextView
        android:id="@+id/title"
        android:textColor="@color/title"
        android:textSize="16dp"
        android:textStyle="bold"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/genre"
        android:layout_below="@id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/year"
        android:textColor="@color/year"
        android:layout_width="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/desc"
        android:textColor="@color/year"
        android:layout_width="match_parent"
        android:layout_alignTop="@+id/genre"
        android:layout_height="wrap_content" />

</RelativeLayout>

最后是视频:

Video showing the code works just fine

TG

// UPDATE_1 ***

完整的源代码以zip文件格式共享:

source code

答案 1 :(得分:0)

如果我正确理解您的问题,您应该在ViewHolder课程中设置视图的点击监听器。

答案 2 :(得分:0)

试试这个, 你不需要调用 int currentPosition = viewHolder.getAdapterPosition(); 而是可以使用onBindeViewHolder方法本身的位置,来改变你需要的背景调用holder.itemView.setOnCLickListner();如果你想选择取消选择itemRow,那么只需将所选位置的标志保持为选中/未选中。