滚动RecyclerView时,cardview上的数据被更改

问题描述 投票:1回答:1

我是Android应用程序开发的新手。我有一个类,其中包含RecyclerView。

public class ScreenOne extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

    private RecyclerView mRecyclerView;
    private FilmSetAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    SwipeRefreshLayout mSwipeRefreshLayout;

    RequestTask requestTask;
    ArrayList<Film> listOfFilms;
    ArrayList<Cinema> listOfCinemas;
    ArrayList<String> cityIDs;

    public ScreenOne() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.screen_one, container,
                false);

        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
        mLayoutManager = new LinearLayoutManager(getActivity());
        //mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(mLayoutManager);
        //mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        listOfFilms = new ArrayList<>();
        mAdapter = new FilmSetAdapter(listOfFilms);
        mRecyclerView.setAdapter(mAdapter);

        mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh);
        mSwipeRefreshLayout.setOnRefreshListener(this);
        mSwipeRefreshLayout.setColorScheme(R.color.blue, R.color.cyan, R.color.grey_blue, R.color.lightblue);

        try {
            updateFilms();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return rootView;
    }


    private void updateFilms() throws InterruptedException {
        requestTask = new RequestTask();
        try {
            requestTask.execute().get();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    private boolean isNetworkConnected() {
        ConnectivityManager cm =
                (ConnectivityManager) getActivity().getSystemService(getActivity().CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        return netInfo != null && netInfo.isConnectedOrConnecting();
    }

    @Override
    public void onRefresh() {
        Toast.makeText(getActivity(), R.string.refresh_started, Toast.LENGTH_SHORT).show();
        mSwipeRefreshLayout.setRefreshing(true);
        mAdapter.setDataset(new ArrayList<Film>());
        mAdapter.notifyDataSetChanged();
        try {
            updateFilms();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        DatabaseHandler database = new DatabaseHandler(getActivity());
        mAdapter = new FilmSetAdapter(database.getAllFilms());
        mRecyclerView.swapAdapter(mAdapter, false);
        database.close();

        mSwipeRefreshLayout.postDelayed(new Runnable() {
            @Override
            public void run() {
                mSwipeRefreshLayout.setRefreshing(false);
                Toast.makeText(getActivity(), R.string.refresh_finished, Toast.LENGTH_SHORT).show();
            }
        }, 3000);
    }

    class RequestTask extends AsyncTask<Void, Void, Void> {

        protected void getPreferenciesCity()
        {
            cityIDs = new ArrayList<>();
            SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
            SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
            Set<String> selections = sharedPrefs.getStringSet("cities", null);
            try {
                Log.d("SHARED PREFERENCES CITY", selections.toString());
                cityIDs.addAll(selections);
            }catch (NullPointerException e){Log.d("SHARED PREFERENCES CITY", "SP are empty");}

        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            listOfFilms = new ArrayList<>();
            getPreferenciesCity();
        }

        @Override
        protected Void doInBackground(Void... params) {
            if(isNetworkConnected()) {
                DatabaseHandler database = new DatabaseHandler(getActivity());
                database.clearFilms();
                try {
                    HttpHandler httpHandler = new HttpHandler();
                    listOfFilms = new ArrayList<>(httpHandler.listOfFilmsRequest(cityIDs));
                    listOfCinemas = new ArrayList<>(httpHandler.listOfCinemasRequest());

                    Film film;
                    Cinema cinema;
                    for (Iterator<Film> filmiterator = listOfFilms.iterator(); filmiterator.hasNext(); ) {
                        film = filmiterator.next();
                        if (database.isInDatabase(film.getID()))
                            database.updateFilm(film);
                        else
                            database.addFilm(film);
                    }

                    for (Iterator<Cinema> cinemaiterator = listOfCinemas.iterator(); cinemaiterator.hasNext(); ) {
                        cinema = cinemaiterator.next();
                        if (database.CinemaIsInDatabase(cinema.getIDCinema()))
                            database.updateCinema(cinema);
                        else
                            database.addCinema(cinema);
                    }
                    database.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            DatabaseHandler database = new DatabaseHandler(getActivity());
            mAdapter.setDataset(database.getAllFilms());
            mAdapter.notifyDataSetChanged();
        }
    }
}

它执行一个方法,该方法位于AsyncTask类中。此方法从服务器下载数据,首先将其放入数据库,然后设置回收者视图适配器。问题在于有时滚动时会更改文本数据。 See attached video.

适配器的代码是:

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

    private ArrayList<Film> mDataset;
    final static String LOG_TAG = "FilmSetAdapter";

    public void setDataset(ArrayList<Film> allFilms) {
        mDataset = new ArrayList<>(allFilms);
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public static TextView filmTitle;
        public TextView country;
        public TextView ticketsFrom;
        public TextView rating;
        public TextView format;
        public ImageView poster;
        public int id;

        public ViewHolder(final View itemView) {
            super(itemView);
            filmTitle = (TextView) itemView.findViewById(R.id.filmtitle);
            country = (TextView)itemView.findViewById(R.id.country);
            ticketsFrom = (TextView) itemView.findViewById(R.id.ticketsfrom);
            rating = (TextView)itemView.findViewById(R.id.rating);
            poster = (ImageView) itemView.findViewById(R.id.poster);
            format = (TextView) itemView.findViewById(R.id.format);
            format.setTypeface(null, Typeface.BOLD_ITALIC);
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.cardview, parent, false);

        final ViewHolder vh = new ViewHolder(v);
        v.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                Log.d(LOG_TAG, "Нажата карточка. Вызов из activity "+v.toString());
                Intent intent = new Intent(v.getContext(),FilmInfoActivity.class);
                intent.putExtra("EXTRA_FILM_ID", vh.id);
                v.getContext().startActivity(intent);
            }
        });
        return vh;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.filmTitle.setText(mDataset.get(position).getTitle().toString()+" ID="+mDataset.get(position).getID()+" POS="+position);
        holder.country.setText(mDataset.get(position).getCountry());
        holder.ticketsFrom.setText(holder.ticketsFrom.getContext().getString(R.string.tickets_from) +
                mDataset.get(position).getRating().toString());
        holder.rating.setText(holder.rating.getContext().getString(R.string.rating_kinopoisk) +
                mDataset.get(position).getRating());
        holder.id = mDataset.get(position).getID();
        holder.format.setText(mDataset.get(position).getFormat());

        Picasso.with(holder.poster.getContext()).
                load(mDataset.get(position).getPoster()).
                skipMemoryCache().
                into(holder.poster);
    }

    @Override
    public int getItemCount() {
        if(mDataset != null)
            return mDataset.size();
        return 0;
    }

    public FilmSetAdapter(ArrayList<Film> myDataset) {
        mDataset = new ArrayList<>(myDataset);
    }
}

我不知道如何解决。

android android-recyclerview android-cardview
1个回答
0
投票

似乎您的代码中有一个拼写错误,请看一下,您的ViewHolder中有此错误:

    public static TextView filmTitle;

但是您可以像处理其他字段一样使用它:

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    holder.filmTitle.setText(mDataset.get(position).getTitle() + ...);
...   
}

作为新手,为您提供的一些建议:只是..多注意您的代码,您将可以很好地进行编程:)

© www.soinside.com 2019 - 2024. All rights reserved.