应用程序停止,因为按下了按钮?

时间:2018-12-23 14:32:21

标签: java android

我有一个小的应用程序,有时会停止并显示错误,因为我已按下按钮buttonViewOption。有时,当您按下按钮时,应用程序停止了编写最佳代码以避免错误的最佳方法。

尝试帮助我提出更好的建议或编写替换代码。

查看代码

package com.sab99r.recyclerview_loadmore;

    import android.content.Context;
    import android.support.v7.widget.PopupMenu;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;

    import java.util.List;

    /**
     * Created by sab99r
     */
    public class MoviesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        public final int TYPE_MOVIE = 0;
        public final int TYPE_LOAD = 1;

        static Context context;
        List<MovieModel> movies;
        OnLoadMoreListener loadMoreListener;
        boolean isLoading = false, isMoreDataAvailable = true;

        /*
        * isLoading - to set the remote loading and complete status to fix back to back load more call
        * isMoreDataAvailable - to set whether more data from server available or not.
        * It will prevent useless load more request even after all the server data loaded
        **/


        public MoviesAdapter(Context context, List<MovieModel> movies) {
            this.context = context;
            this.movies = movies;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(context);
            if(viewType==TYPE_MOVIE){
                return new MovieHolder(inflater.inflate(R.layout.row_movie,parent,false));
            }else{
                return new LoadHolder(inflater.inflate(R.layout.row_load,parent,false));
            }
        }


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

            if(position>=getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null){
                isLoading = true;
                loadMoreListener.onLoadMore();
            }
            if(getItemViewType(position)==TYPE_MOVIE){
                ((MovieHolder)holder).bindData(movies.get(position));
            }

            // tvRating

            // See Here 
        ((MovieHolder)holder).buttonViewOption.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    Toast.makeText(context, ""+ position, Toast.LENGTH_LONG).show();
                }
            });
        }


        @Override
        public int getItemViewType(int position) {
            if(movies.get(position).type.equals("movie")){
                return TYPE_MOVIE;
            }else{
                return TYPE_LOAD;
            }

        }




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

        /* VIEW HOLDERS */

        static class MovieHolder extends RecyclerView.ViewHolder{
            TextView tvTitle;
            TextView tvRating;
            Button buttonViewOption;
            public MovieHolder(View itemView) {
                super(itemView);
                tvTitle=(TextView)itemView.findViewById(R.id.title);
                tvRating=(TextView)itemView.findViewById(R.id.rating);
                buttonViewOption = (Button) itemView.findViewById(R.id.textViewOptions);
            }

            void bindData(MovieModel movieModel){
                tvTitle.setText(movieModel.post_writer);
                tvRating.setText(movieModel.post_content);
            }
        }

        static class LoadHolder extends RecyclerView.ViewHolder{
            public LoadHolder(View itemView) {
                super(itemView);
            }
        }

        public void setMoreDataAvailable(boolean moreDataAvailable) {
            isMoreDataAvailable = moreDataAvailable;
        }

        /* notifyDataSetChanged is final method so we can't override it
             call adapter.notifyDataChanged(); after update the list
             */
        public void notifyDataChanged(){
            notifyDataSetChanged();
            isLoading = false;
        }


        interface OnLoadMoreListener{
            void onLoadMore();
        }

        public void setLoadMoreListener(OnLoadMoreListener loadMoreListener) {
            this.loadMoreListener = loadMoreListener;
        }
    }

1 个答案:

答案 0 :(得分:1)

您的MoviesAdapter能够显示两种类型的ViewHolderMovieHolderLoadHolder。在没有看到堆栈跟踪的情况下,我猜测onBindViewHolder正在处理LoadHolder,但是您在转换为MovieHolder之前没有进行检查。让我们看一下onBindViewHolder()

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

        if(position>=getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null){
            isLoading = true;
            loadMoreListener.onLoadMore();
        }
        if(getItemViewType(position)==TYPE_MOVIE){
            ((MovieHolder)holder).bindData(movies.get(position));
        }

到目前为止,您正在检查视图类型是否为电影。因此,如果是这样,则可以保证holder属于MovieHolder类。您的错误在下一行:

        // See Here 
    ((MovieHolder)holder).buttonViewOption.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Toast.makeText(context, ""+ position, Toast.LENGTH_LONG).show();
            }
        });
    }

您现在不在if语句之外,因此holder现在可以是MovieHolderLoadHolder,如果您使用ClassCastException正在尝试投射LoadHolder。我建议像这样重写您的方法:

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

        if(position>=getItemCount()-1 && isMoreDataAvailable && !isLoading && loadMoreListener!=null){
            isLoading = true;
            loadMoreListener.onLoadMore();
        }
        if(getItemViewType(position)==TYPE_MOVIE){
            MovieHolder movieHolder = (MovieHolder) holder;
            movieHolder.bindData(movies.get(position));

            // tvRating
            movieHolder.buttonViewOption.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(context, ""+ position, Toast.LENGTH_LONG)
                            .show();
                }
            });
        }        
    }