为什么RecyclerView CustomAdaper Filter和onViewRecycled()都没有在android中一起工作?

时间:2017-06-23 05:52:10

标签: android filtering recycler-adapter

我的应用程序需要在customAdapter上过滤,所以我在CustomAdapter中实现了Filter

在CustomAdapter中我放了谷歌地图。当适配器被回收时,谷歌地图图钉和地图视图会针对该解决方案进行更改,我使用onViewRecycled()方法,并在其中设置纬度和经度并在Google地图视图上设置标记。

但问题是,当我实现过滤器逻辑时,应用程序崩溃并给我ArrayIndexOutOfBound异常,错误指向我onViewRecycled()方法。

请帮我解决这个问题。

我的适配器和活动代码如下:

PostListAdapter.java

public class PostListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable{

    Context mcontext;
    LayoutInflater inflater;

    View view;
    RecyclerViewHolder recyclerViewHolder;
    FragmentManager fm;
    MapView map;
    GPSTracker gps;
    private double latitude=0.0, longitude=0.0;
    LatLng latlongs;
    Geocoder geocoder;
    List<Address> addressList;
    GoogleMap thisMap;
    String mapTitle = null;
    String mapSnnipet = null;
    boolean isAgreePost;
    List<GetPostCallBack> getPostCallBackList;
    List<GetPostCallBack> getPostCallBackListFiltered=new ArrayList<>();
    Dialog dialog;
    String User_Id = "";
    double latitudeForMarker=0.0, longitudeForMarker=0.0;


    public PostListAdapter(Context mcontext, FragmentManager fm, List<GetPostCallBack> getPostCallBackList) {

        inflater = null;
        this.mcontext = mcontext;
        this.fm = fm;
        this.getPostCallBackList = getPostCallBackList;
        this.getPostCallBackListFiltered.addAll(getPostCallBackList);
        User_Id = Functions.getStringPref(mcontext, FindExperience.USER_ID);
        Log.d("TAG", "PostListAdapter: " + User_Id);
        inflater = (LayoutInflater) this.mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        gps = new GPSTracker(mcontext);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout_home, parent, false);
        recyclerViewHolder = new RecyclerViewHolder(view);
        return recyclerViewHolder;
    }

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

        recyclerViewHolder = (RecyclerViewHolder) holder;
        thisMap = recyclerViewHolder.gMap;

        if (!getPostCallBackList.get(position).getProfilePicture().equals("")) {
            Picasso.with(mcontext).load(getPostCallBackList.get(position).getProfilePicture()).placeholder(android.R.drawable.ic_menu_gallery).into(recyclerViewHolder.ivPostUserImg);
        }
        recyclerViewHolder.tvPostUserName.setText(getPostCallBackList.get(position).getFullName());
        recyclerViewHolder.tvPostQuote.setText(getPostCallBackList.get(position).getUserNote());
        recyclerViewHolder.tvPostCreatedDate.setText(getPostCallBackList.get(position).getPostDate());
        recyclerViewHolder.tvPostTitle.setText(getPostCallBackList.get(position).getPostTitle());
        recyclerViewHolder.tvPostCategorySubCategory.setText(getPostCallBackList.get(position).getCatName() + "/" + getPostCallBackList.get(position).getSubCatName());
        recyclerViewHolder.tvPostContent.setText(getPostCallBackList.get(position).getPostContent());

        recyclerViewHolder.btnAgree.setText("AGREE (" + getPostCallBackList.get(position).getTotalLike() + ")");
        recyclerViewHolder.btnDisagree.setText("DISAGREE (" + getPostCallBackList.get(position).getTotalDislike() + ")");
        final Activity activity = (Activity) mcontext;
        recyclerViewHolder.ReadMore.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent i = new Intent(mcontext, PostDetailsActivity.class);
                i.putExtra("Details", getPostCallBackList.get(position));
                activity.startActivity(i);
                activity.overridePendingTransition(R.anim.left_in, R.anim.left_out);
            }
        });
        recyclerViewHolder.btnAgree.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Intent i = new Intent(mcontext, AgreeListActivity.class);
                activity.startActivity(i);
                activity.overridePendingTransition(R.anim.left_in, R.anim.left_out);
                return true;
            }
        });
        recyclerViewHolder.btnAgree.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                apiCallForUserAgreeDisAgree(getPostCallBackList.get(position).getPostId(), User_Id, "1");
            }
        });
        recyclerViewHolder.btnDisagree.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                apiCallForUserAgreeDisAgree(getPostCallBackList.get(position).getPostId(), User_Id, "0");
            }
        });
        recyclerViewHolder.btnDisagree.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Intent i = new Intent(mcontext, DisAgreeListActivity.class);
                activity.startActivity(i);
                activity.overridePendingTransition(R.anim.left_in, R.anim.left_out);
                return true;
            }
        });
        recyclerViewHolder.btnComment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(mcontext, CommentListActivity.class);
                activity.startActivity(i);
                activity.overridePendingTransition(R.anim.left_in, R.anim.left_out);

            }
        });
    }

    //Recycling GoogleMap for list item
    @Override
    public void onViewRecycled(RecyclerView.ViewHolder holder) {
        // Cleanup MapView here?
        if (recyclerViewHolder.gMap != null) {
            int position = recyclerViewHolder.getPosition();
            recyclerViewHolder.gMap.clear();
            recyclerViewHolder.gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
            latitude=0.0;
            longitude=0.0;
            if (!(getPostCallBackList.get(position).getLangitude().equals("") && getPostCallBackList.get(position).getLongitude().equals(""))) {
                latitude = Double.parseDouble(getPostCallBackListFiltered.get(position).getLangitude());
                longitude = Double.parseDouble(getPostCallBackListFiltered.get(position).getLongitude());
                Log.d("TAG", "onBindViewHolder: recycled : " + latitude + " " + longitude);
                latlongs = new LatLng(latitude, longitude);
                // For zooming automatically to the location of the marker
//                CameraPosition cameraPosition = new CameraPosition.Builder().target(latlongs).zoom(14).build();
                geocoder = new Geocoder(mcontext, Locale.getDefault());
                try {
                    addressList = geocoder.getFromLocation(latitude, longitude, 1);
                    if (addressList != null && addressList.size() > 0) {
                        Address address = addressList.get(0);
                        StringBuilder sb = new StringBuilder();
                        StringBuilder sb1 = new StringBuilder();
                        for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                            sb1.append(address.getAddressLine(i)).append("\n");
                            mapSnnipet = sb1.toString();
                        }
                        sb.append(address.getLocality());
                        mapTitle = sb.toString();
                    }
                    Log.d("TAG", "onMapReady: " + addressList.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                MarkerOptions a = new MarkerOptions().position(latlongs).title(mapTitle).snippet(mapSnnipet).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));

                recyclerViewHolder.gMap.addMarker(a);
                recyclerViewHolder.gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlongs, 18.0f));

            }
        }
    }

    public void apiCallForUserAgreeDisAgree(String post_id, String user_id, String status) {
        if (NetworkUtils.getConnectivityStatus(mcontext) != 0) {
            Log.d("TAG", "apiCallForAddPost: User_id : " + user_id);
            Log.d("TAG", "apiCallForAddPost: Post id : " + post_id);
            Log.d("TAG", "apiCallForAddPost: status : " + status);

            API api = App.retrofit.create(API.class);
            final Call<UserAgreeCallBack> userAgreeCallBackCall = api.isAgree(post_id, user_id, status);

            userAgreeCallBackCall.enqueue(new Callback<UserAgreeCallBack>() {
                @Override
                public void onResponse(Call<UserAgreeCallBack> call, Response<UserAgreeCallBack> response) {

                    if (response.code() == 200) {
                        if (response.body().getStatus().equalsIgnoreCase("success")) {
                            if (NetworkUtils.getConnectivityStatus(mcontext) != 0) {
                                dialog = ProgressDialog.show(mcontext, "", "Please Wait.....");
                                dialog.show();
                                API api = App.retrofit.create(API.class);
                                final Call<List<GetPostCallBack>> getPostCallBackCall = api.getAllPost();

                                getPostCallBackCall.enqueue(new Callback<List<GetPostCallBack>>() {
                                    @Override
                                    public void onResponse(Call<List<GetPostCallBack>> call, Response<List<GetPostCallBack>> response) {
                                        if (dialog != null && dialog.isShowing()) {
                                            dialog.dismiss();
                                        }
                                        if (response.code() == 200) {
                                            updateEmployeeListItems(response.body());
                                        }
                                    }

                                    @Override
                                    public void onFailure(Call<List<GetPostCallBack>> call, Throwable t) {
                                        if (dialog.isShowing() && dialog != null) {
                                            dialog.dismiss();
                                        }
                                        Toast.makeText(mcontext, t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                                        Log.d("TAG", "onFailure: " + t.getLocalizedMessage());
                                    }
                                });

                            } else {
                                Toast.makeText(mcontext, "Please check your internet connection", Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<UserAgreeCallBack> call, Throwable t) {
                    Toast.makeText(mcontext, t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                    Log.d("TAG", "onFailure: " + t.getLocalizedMessage());
                }
            });

        } else {
            Toast.makeText(mcontext, "Please check your internet connection", Toast.LENGTH_SHORT).show();
        }
    }

    public void updateEmployeeListItems(List<GetPostCallBack> employees) {
        final GetPostCallBack diffCallback = new GetPostCallBack(this.getPostCallBackList, employees);
        final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);
        this.getPostCallBackList.clear();
        this.getPostCallBackList.addAll(employees);
        diffResult.dispatchUpdatesTo(this);
    }


    @Override
    public int getItemCount() {
        return getPostCallBackList == null ? 0 : getPostCallBackList.size();
    }


    private Filter fRecords;
    @Override
    public Filter getFilter() {
        if(fRecords == null) {
            fRecords=new RecordFilter();
        }
        return fRecords;
    }


    class RecyclerViewHolder extends RecyclerView.ViewHolder implements OnMapReadyCallback {

        GoogleMap gMap;
        MapView map;

        @BindView(R.id.tvReadMore)
        TextView ReadMore;

        @BindView(R.id.btnAgree)
        Button btnAgree;

        @BindView(R.id.btnDisagree)
        Button btnDisagree;

        @BindView(R.id.btnComment)
        Button btnComment;

        @BindView(R.id.ivPostUserImg)
        CircularImageView ivPostUserImg;

        @BindView(R.id.tvPostUserName)
        TextView tvPostUserName;

        @BindView(R.id.tvPostQuote)
        TextView tvPostQuote;

        @BindView(R.id.tvPostCreatedDate)
        TextView tvPostCreatedDate;

        @BindView(R.id.tvPostTitle)
        TextView tvPostTitle;

        @BindView(R.id.tvPostCategorySubCategory)
        TextView tvPostCategorySubCategory;

        @BindView(R.id.tvPostContent)
        TextView tvPostContent;

        public RecyclerViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
            map = (MapView) view.findViewById(R.id.mapAdapter);
            if (map != null) {
                map.onCreate(null);
                map.onResume();
                map.getMapAsync(this);
            }
        }

        @Override
        public void onMapReady(GoogleMap googleMap) {
            MapsInitializer.initialize(getApplicationContext());
            gMap = googleMap;
            final int position = getPosition();
            if (gps.canGetLocation()) {
                latitude=0.0;
                longitude=0.0;
                if (!(getPostCallBackList.get(position).getLangitude().equals("") && getPostCallBackList.get(position).getLongitude().equals(""))) {
                    latitude = Double.parseDouble(getPostCallBackList.get(position).getLangitude());
                    longitude = Double.parseDouble(getPostCallBackList.get(position).getLongitude());
                    Log.d("TAG", "onBindViewHolder: " + latitude + " " + longitude);

                    latlongs = new LatLng(latitude, longitude);
                    // For zooming automatically to the location of the marker
//                CameraPosition cameraPosition = new CameraPosition.Builder().target(latlongs).zoom(14).build();
                    geocoder = new Geocoder(mcontext, Locale.getDefault());
                    try {
                        addressList = geocoder.getFromLocation(latitude, longitude, 1);
                        if (addressList != null && addressList.size() > 0) {
                            Address address = addressList.get(0);
                            StringBuilder sb = new StringBuilder();
                            StringBuilder sb1 = new StringBuilder();
                            for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                                sb1.append(address.getAddressLine(i)).append("\n");
                                mapSnnipet = sb1.toString();
                            }
                            sb.append(address.getLocality());
                            mapTitle = sb.toString();
                        }
                        Log.d("TAG", "onMapReady: " + addressList.toString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    MarkerOptions a = new MarkerOptions().position(latlongs).title(mapTitle).snippet(mapSnnipet).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
                    if (gMap != null) {
                        gMap.addMarker(a);
                        gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlongs, 18.0f));
                        gMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
                            @Override
                            public boolean onMarkerClick(Marker marker) {
                                if (marker != null){
                                    latitudeForMarker = Double.parseDouble(getPostCallBackList.get(position).getLangitude());
                                    longitudeForMarker = Double.parseDouble(getPostCallBackList.get(position).getLongitude());
                                    Log.d("TAG", "onMarkerClick: on viewcreated : http://maps.google.com/maps?daddr="+latitudeForMarker+","+longitudeForMarker);
//                                Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
//                                        Uri.parse("google.navigation:q="+mapSnnipet));

                                    Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
                                            Uri.parse("http://maps.google.com/maps?daddr="+latitudeForMarker+","+longitudeForMarker));
                                    mcontext.startActivity(intent);
                                    return true;
                                }
                                return false;
                            }
                        });
                    }
                }
            }
        }
    }
    //filter class
    private class RecordFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();

            //Implement filter logic
            // if edittext is null return the actual list
            if (constraint == null || constraint.length() == 0) {
                //No need for filter
//                getPostCallBackList.clear();
//                getPostCallBackList.addAll(getPostCallBackListFiltered);
                results.values = getPostCallBackListFiltered;
                results.count = getPostCallBackListFiltered.size();

            } else {
                //Need Filter
                // it matches the text  entered in the edittext and set the data in adapter list
                ArrayList<GetPostCallBack> fRecords = new ArrayList<>();

                for (GetPostCallBack s : getPostCallBackListFiltered) {
                    if (s.getFullName().toLowerCase().contains(constraint.toString().toLowerCase().trim())) {
                        fRecords.add(s);
                    }
                }
                results.values = fRecords;
                results.count = fRecords.size();
            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint,FilterResults results) {

            //it set the data from filter to adapter list and refresh the recyclerview adapter
            getPostCallBackList = (ArrayList<GetPostCallBack>) results.values;
            notifyDataSetChanged();
        }
    }
}

HomeActivity.java

public class HomeActivity extends FooterController implements FragmentManager.OnBackStackChangedListener {

    @BindView(R.id.recyclerHome)
    RecyclerView recyclerHome;


    @BindView(R.id.fab)
    Button fab;

    @BindView(R.id.toolbar)
    Toolbar toolbar;

    @BindView(R.id.actvLocationFilter)
    AutoCompleteTextView actvLocationFilter;

    public static ImageView ivSearch;

    @BindView(R.id.etSearch)
    EditText etSearch;

    public static TextView tvTitle;

    public static TextView tvBack;

    @BindView(R.id.tvPost)
    TextView tvPost;

    //@BindView(R.id.ivDrawer)
    public static ImageView ivDrawer;

    @BindView(R.id.drawer_layout)
    DrawerLayout drawer;

    @BindView(R.id.navList)
    ListView mDrawerList;

    private ArrayAdapter<String> drawerAdapter;
    LinearLayoutManager linearLayoutManager;
    PostListAdapter adapter;
    private boolean isLoading = false;
    private boolean isLastPage = false;
    Dialog dialog;
    API api;
    FragmentManager fm;
    GPSTracker gps;
    Boolean buttonStateOpen=false;
    public static int tabPosisiton=0;
    FindExperienceDatabase db;
    List<GetPostCallBack> getPostList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        ButterKnife.bind(this);
        setBottomBar(R.id.bottomBar,false);
        bindWidgets();
        setCustomActionBar();
        addDrawerItems();
        openDrawer();

        fm = getSupportFragmentManager();
        Functions.checkNetworkConnection(HomeActivity.this);
        apiCallForGetPost();
        mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                fm = getSupportFragmentManager();
//                fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
                switch (position){
                    case 0:

                        fm.beginTransaction().replace(R.id.container, new ProfileFragment()).addToBackStack(null).commit();
                        getSupportActionBar().setDisplayHomeAsUpEnabled(true);                  
                        break;

                    case 1:
                        fm.beginTransaction().replace(R.id.container, new SettingFragment()).addToBackStack(null).commit();
                        break;

                    default:
                        break;
                }
                drawer.closeDrawer(Gravity.RIGHT);
            }
        });

    public void apiCallForGetPost(){
        getPostList = new ArrayList<>();
        if (NetworkUtils.getConnectivityStatus(HomeActivity.this)!=0) {
            dialog = ProgressDialog.show(this, "", "Please Wait.....");
            dialog.show();
            API api = App.retrofit.create(API.class);
            final Call<List<GetPostCallBack>> getPostCallBackCall = api.getAllPost();

            getPostCallBackCall.enqueue(new Callback<List<GetPostCallBack>>() {
                @Override
                public void onResponse(Call<List<GetPostCallBack>> call, Response<List<GetPostCallBack>> response) {
                    if (dialog != null && dialog.isShowing()) {
                        dialog.dismiss();
                    }
                    if (response.code()==200){
                        getPostList = response.body();
                        setRecyclerViewAdapter(getPostList);
                    }
                }

                @Override
                public void onFailure(Call<List<GetPostCallBack>> call, Throwable t) {
                    if (dialog.isShowing() && dialog != null) {
                        dialog.dismiss();
                    }
                    Toast.makeText(HomeActivity.this, t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                    Log.d("TAG", "onFailure: " + t.getLocalizedMessage());
                }
            });

        } else {
            Toast.makeText(HomeActivity.this, "Please check your internet connection", Toast.LENGTH_SHORT).show();
        }
    }


    @OnClick(R.id.iv_search)
    public void search(){
        if (etSearch.getVisibility()==View.GONE) {
            etSearch.setVisibility(View.VISIBLE);
            etSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                @Override
                public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                    if (actionId == EditorInfo.IME_ACTION_DONE) {
                        etSearch.clearFocus();
                        InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                        in.hideSoftInputFromWindow(etSearch.getWindowToken(), 0);
                        etSearch.setVisibility(View.GONE);
                        return true;
                    }

                    return false;
                }
            });

            etSearch.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    adapter.getFilter().filter(s.toString()); // Perform Filter on Adapter 
                }

                @Override
                public void afterTextChanged(Editable s) {

                }
            });
        }
        else if (etSearch.getVisibility()==View.VISIBLE){
            InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            in.hideSoftInputFromWindow(etSearch.getWindowToken(), 0);
            etSearch.setVisibility(View.GONE);
        }
    }

    public void setRecyclerViewAdapter(List<GetPostCallBack> getPostList){
        adapter = new PostListAdapter(HomeActivity.this,fm,getPostList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerHome.setLayoutManager(mLayoutManager);
        recyclerHome.smoothScrollToPosition(0);
        recyclerHome.setAdapter(adapter);
    }
    public void openDrawer(){
        getSupportFragmentManager().addOnBackStackChangedListener(this);
        ivDrawer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                drawer.openDrawer(Gravity.RIGHT);
                buttonStateOpen=true;
            }
        });
    }
    private void addDrawerItems() {
        String[] osArray = { "Profile", "Settings" };
        drawerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, osArray);
        mDrawerList.setAdapter(drawerAdapter);
    }

    @Override
    public void onBackStackChanged() {
        shouldDisplayHomeUp();
        Log.d("TAG", "onBackStackChanged: ");
    }
    public void shouldDisplayHomeUp(){
        //Enable Up button only  if there are entries in the back stack
        Log.d("TAG", "shouldDisplayHomeUp: "+getSupportFragmentManager().getBackStackEntryCount());
        boolean canback = getSupportFragmentManager().getBackStackEntryCount() > 0;
        getSupportActionBar().setDisplayHomeAsUpEnabled(canback);
    }
}

1 个答案:

答案 0 :(得分:0)

使用ViewHolder&#34; holder&#34;,将其传递给您的覆盖功能

public void onViewRecycled(RecyclerView.ViewHolder holder)

它将按预期工作。