OnClick Listener仅在第一次单击时更新回收器视图

时间:2017-06-21 00:47:41

标签: android onclick android-recyclerview onclicklistener recycler-adapter

我有一个RecyclerView,显示带有复选框的图像。选中复选框后,与图像关联的项目将保存到数据库中。我还有一个字母索引,当点击它时,调用一个过滤图像的功能,并更新回收者视图,以显示标题对应于单击字母的图像。问题是RecyclerView图像仅在第一次单击时更新。随后的点击次数没有对RecyclerView图像进行更新。我已经检查过,看起来函数确实被随后的点击调用,因为我能够在函数的各个点显示Toast消息。只有RecyclerView没有使用过滤后的图像数据进行更新,我不知道它为什么不更新。任何有关这方面的帮助将不胜感激。

以下是主要活动:

public class AddBrandPage extends AppCompatActivity implements OnClickListener {

    //declare variables
    private RecyclerView recyclerView;
    private RecyclerView.LayoutManager layoutManager;
    private RecyclerView.Adapter adapter;
    private RecyclerView alpharecyclerView;
    private RecyclerView.LayoutManager alphaLayoutManager;
    private RecyclerView.Adapter alphaAdapter;
    private DatabaseReference myRef;
    private DatabaseReference userRef;
    private Button btn_skip;
    private Button btn_save;
    private CheckBox checkbox;
    private String t;
    private String letter;
    List<LogoItems> brandLogo = new ArrayList<>();
    //HashMap<String, String> saveBrands = new HashMap<>();
    List<LogoItems> removedBrandLogo = new ArrayList<>();
    List<String> selectionList = new ArrayList<>();
    List<AlphaItems> alphaList = new LinkedList<>();
    List<LogoItems> tmp = new ArrayList<>();



    String[] alphabets = {"All", "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_brand_page);

        //initialize variables
        btn_skip = (Button) findViewById(R.id.btn_skip);
        btn_save = (Button) findViewById(R.id.btn_save);
        myRef = FirebaseDatabase.getInstance().getReference().child("/brands");
        userRef = FirebaseDatabase.getInstance().getReference().child("/users");


        //calls to load data to arraylists
        loadAlpha();
        loadLogoImgData();


        //set the listener for the buttons click event
        btn_skip.setOnClickListener(this);
        btn_save.setOnClickListener(this);

    }

    private void loadAlpha() {

        for (String alpha : alphabets) {
            alphaList.add(new AlphaItems(alpha));

        }
        startAlphaRecyclerView();

    }

    public void loadLogoImgData() {

        brandLogo.clear();
        myRef.addValueEventListener(new ValueEventListener() {

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for (DataSnapshot brandSnapshot : dataSnapshot.getChildren()) {
                    LogoItems value = brandSnapshot.getValue(LogoItems.class);
                    brandLogo.add(value);
                    tmp.add(value);
                }
                startLogoRecyclerView();
            }


            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

    }


    @Override
    public void onClick(View view) {

        if (view == btn_skip) {
            //if skip button clicked close current window and go to user main page
            finish();
            startActivity(new Intent(getApplicationContext(), UserMainPage.class));

        }
        if (view == btn_save) {
            saveData();
        }

    }


    public void startLogoRecyclerView() {
        // set the main recyclerview view for the logo in the layout
        recyclerView = (RecyclerView) findViewById(R.id.recylView);
        recyclerView.setHasFixedSize(true);

        // set the main layoutManager of the logo recyclerview
        layoutManager = new GridLayoutManager(this, 2);
        recyclerView.setLayoutManager(layoutManager);

        // set the logo recycler view adapter
        adapter = new LogoAdapter(brandLogo, getBaseContext(), AddBrandPage.this);
        recyclerView.setAdapter(adapter);

    }

    public void startAlphaRecyclerView() {
        // set the main recyclerview view for the logo in the layout
        alpharecyclerView = (RecyclerView) findViewById(R.id.alpharecyclerView);
        alpharecyclerView.setHasFixedSize(true);

        // set the main layoutManager of the alpha recyclerview
        alphaLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        alpharecyclerView.setLayoutManager(alphaLayoutManager);

        // set the alpha recycler view adapter
        alphaAdapter = new AlphaAdapter(alphaList, getBaseContext(), AddBrandPage.this);
        alpharecyclerView.setAdapter(alphaAdapter);

    }


    public List<String> prepareSelection(View v, int position) {

        checkbox = (CheckBox) v;

        //check if user selected checkbox and add or remove from list
        //if (checkbox.isChecked()) {
        selectionList.add(brandLogo.get(position).getName());

        //} else {
        // selectionList.remove(brandLogo.get(position).getLogo());

        //}
        return selectionList;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof AddBrandPage)) return false;
        AddBrandPage that = (AddBrandPage) o;

        if (t != null ? !t.equals(that.t) : that.t != null) return false;
        return letter != null ? letter.equals(that.letter) : that.letter == null;

    }

    @Override
    public int hashCode() {
        int result = t != null ? t.hashCode() : 0;
        result = 31 * result + (letter != null ? letter.hashCode() : 0);
        return result;
    }

    public void updateLogoDisplay(final String letter) {
        int i = 0;
        brandLogo.clear();
        brandLogo.addAll(tmp);

        if (!(letter.equals("All"))) {
            //Iterator<LogoItems> iter = brandLogo.iterator();

            for (i=0; i< tmp.size(); i++){ //Iterator<LogoItems> iter = tmp.iterator(); iter.hasNext(); ) {
                //while (iter.hasNext()) {
                LogoItems r = tmp.get(i);
                final String c = r.getName();
                if (c != null) {
                    String t = c.substring(0, 1);
                    if (t != null) {
                        if (c != null) {

                            if ((letter.equals(t))) {
                                //brandLogo.remove(r);
                                removedBrandLogo.add(r);
                                //iter.remove();

                            }
                        }
                    }
                } else {
                }
            }
            brandLogo.clear();
            brandLogo.addAll(removedBrandLogo);

            adapter.notifyDataSetChanged();
            //startLogoRecyclerView();
           }

    }



    public void saveData() {

        final FirebaseAuth mAuth;
        final DatabaseReference userRef;

        mAuth = FirebaseAuth.getInstance();
        userRef = FirebaseDatabase.getInstance().getReference().child("users");
        DatabaseReference curUser = userRef.child(mAuth.getCurrentUser().getUid());
        curUser.child("brands").setValue(selectionList);//save selected items to the database

    }

}

这是字母表适配器(AlphaAdapter.java):

public class AlphaAdapter extends RecyclerView.Adapter<AlphaAdapter.AlphaViewHolder> {

    //declare variables
    List<AlphaItems> alphaList = new ArrayList<>();
    private AddBrandPage addBrandPage;
    private Context context;



    //the constructor
    public AlphaAdapter (List<AlphaItems> alphaList, Context context, AddBrandPage addBrandPage){
        this.alphaList = alphaList;
        this.context = context;
        this.addBrandPage = addBrandPage;

    }


    @Override
    public AlphaAdapter.AlphaViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.alpha_items, parent, false);
        AlphaViewHolder alphaViewHolder = new AlphaViewHolder(view,addBrandPage);
        return alphaViewHolder;
    }

    @Override
    public void onBindViewHolder(AlphaAdapter.AlphaViewHolder holder, int position) {
        holder.txt_alpha.setText(alphaList.get(position).getLetter());

    }

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

    public class AlphaViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        //declare variables
        private TextView txt_alpha;
        private AddBrandPage addBrandPage;


        //the constructor
        public AlphaViewHolder (View itemView, AddBrandPage addBrandPage){
            super(itemView);
            this.addBrandPage = addBrandPage;



            //initialize variables
            txt_alpha = (TextView) itemView.findViewById(R.id.txt_alpha);

            //set click listener
            txt_alpha.setOnClickListener(this);


        }



        @Override
        public void onClick(View v) {
            int position = getAdapterPosition();
            String letter = alphaList.get(position).getLetter();
            addBrandPage.updateLogoDisplay(letter);

        }
    }

}

这是字母索引布局(alpha_items.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="40dp"
    android:layout_height="match_parent"
    android:scrollbars="horizontal">

    <android.support.v7.widget.CardView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:scrollbars="horizontal"
        >

        <TextView
            android:id="@+id/txt_alpha"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="2dp"
            android:text="A"
            android:textSize="18dp"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:gravity="center_vertical"
            />
    </android.support.v7.widget.CardView>
</LinearLayout>

以下是显示图像的徽标适配器(LogoAdapter.java):

public class LogoAdapter extends RecyclerView.Adapter<LogoAdapter.LogoViewHolder> {

    public static LogoAdapter adapter;
    //declaration fo variables
    List<LogoItems> brandLogo = new ArrayList<>();
    List<String> selector = new ArrayList<>();
    private AddBrandPage addBrandPage;
    private Context context;
    private CheckBox checkbox;


    //the constructor
    public LogoAdapter(List<LogoItems> brandLogo, Context context, AddBrandPage addBrandPage) {
        this.brandLogo = brandLogo;
        this.context = context;
        this.addBrandPage = addBrandPage;

    }


    @Override
    public LogoAdapter.LogoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.logo_items, parent, false);
        LogoViewHolder logoViewHolder = new LogoViewHolder(view,addBrandPage);
        return logoViewHolder;
    }

    @Override
    public void onBindViewHolder(LogoAdapter.LogoViewHolder holder, int position) {
        Picasso.with(context).load(brandLogo.get(position).getLogo()).into(holder.logo);

    }

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


    //viewholder class
    public class LogoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        //declare variables
        private AddBrandPage addBrandPage;
        private ImageView logo;
        private CheckBox checkbox;



        //ViewHolder constructor
        public LogoViewHolder(View itemView, AddBrandPage addBrandPage) {
            super(itemView);

            //initialize variables inside the viewholder constructor
            this.addBrandPage = addBrandPage;
            logo = (ImageView) itemView.findViewById(R.id.img_logo);
            checkbox = (CheckBox) itemView.findViewById(R.id.checkbox);


            //set click listener for the checkbox
            checkbox.setOnClickListener(this);
            logo.setOnClickListener(this);



        }


        @Override
        public void onClick(View v) {
            int position = getAdapterPosition();
            addBrandPage.prepareSelection(v, position);//method call to populate an arraylist with selected items


        }
    }
}

这是图像的xml布局(Logo_items.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cardView="http://schemas.android.com/apk/res-auto"
    android:id="@+id/logo_container"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="@android:color/darker_gray"
    android:gravity="center_vertical|center_horizontal"
    android:orientation="vertical"
    android:paddingBottom="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="10dp"
    android:visibility="visible"
    cardView:layout_collapseParallaxMultiplier="1.0">

    <android.support.v7.widget.CardView
        android:layout_width="155dp"
        android:layout_height="100dp"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp"
        cardView:cardBackgroundColor="@android:color/white">


        <GridLayout
            android:id="@+id/cardView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal|center_vertical"
            android:orientation="vertical">


            <ImageView
                android:id="@+id/img_logo"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_column="1"
                android:layout_gravity="center_horizontal|center_vertical"
                android:layout_row="0"
                android:paddingBottom="5dp"
                android:paddingLeft="2.5dp"
                android:paddingRight="2.5dp"
                android:paddingTop="5dp">

            </ImageView>

        </GridLayout>

        <CheckBox
            android:id="@+id/checkbox"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_marginLeft="130dp"
            android:layout_marginTop="66dp"
            android:onClick="addBrandpage.prepareSelection"
            />

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

</LinearLayout>

这是logcat:

06-16 09:16:24.404 12319-12324/com.test.test I/art: Do partial code cache collection, code=499KB, data=310KB
06-16 09:16:24.429 12319-12324/com.test.test I/art: After code cache collection, code=499KB, data=315KB
06-16 09:16:24.429 12319-12324/com.test.test I/art: Increasing code cache capacity to 2MB
06-16 09:16:32.258 12319-12326/com.test.test W/art: Suspending all threads took: 13.640ms
06-16 09:16:32.260 12319-12319/com.test.test I/Choreographer: Skipped 53 frames!  The application may be doing too much work on its main thread.

1 个答案:

答案 0 :(得分:0)

我能够解决问题。

活动页面上有两个OnClickListeners。一个用于checkboxes,一个用于字母索引。发生的事情是,当点击一个字母表时,OnClickListeners都会被触发。因此,在第一次点击时,字母OnClickListener执行完成,RecyclerView更新过滤后的图像。但是在第二次单击时,当它似乎执行该函数时,该函数没有完全完成,因为程序与checkbox OnClickListener混淆。解决方案是在onClick方法中添加if(条件),以便程序知道点击适用于哪个OnClickListener。 AlphaAdapter类中的修改如下:

@Override
    public void onClick(View view) {
        if (view == txt_alpha) {
            int position = getAdapterPosition();
            String letter = alphaList.get(position).getLetter();
            addBrandPage.updateLogoDisplay(letter);
        }
    }

对LogoAdapter类进行了类似的修改。