【问题标题】:Android read Firebase CheckBox acting weirdAndroid 读取 Firebase CheckBox 行为怪异
【发布时间】:2020-01-03 06:52:35
【问题描述】:

我在项目中有以下内容:

  1. MainActivity
  2. FirebaseHelper
  3. CustomAdapter
  4. Person
  5. one_line_list_item.xml

MainActivity 类

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        context = this;
        mListView = (ListView) findViewById(R.id.list_view);
        searchView = (SearchView) findViewById(R.id.search);
        //searchView.setIconifiedByDefault(true);
        searchView.setSubmitButtonEnabled(true);
        //initialize firebase database
        db = FirebaseDatabase.getInstance().getReference();
        helper = new FirebaseHelper(db, this, mListView);

        adapter = new CustomAdapter(context, helper.people);

FirebaseHelper 类

public class FirebaseHelper {

    DatabaseReference db;
    Boolean saved;
    ArrayList<Person> people = new ArrayList<>();
    ListView mListView;
    Context c;
    CustomAdapter adapter;

    public FirebaseHelper(DatabaseReference db, Context context, ListView mListView) {
        this.db = db;
        this.c = context;
        this.mListView = mListView;
        this.retrieve();
    }

    public ArrayList<Person> retrieve() {
        db.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                people.clear();
                if (dataSnapshot.exists() && dataSnapshot.getChildrenCount() > 0) {
                    for (DataSnapshot ds : dataSnapshot.getChildren()) {
                        //Now get Person Objects and populate our arraylist.
                        Person person = ds.getValue(Person.class);
                        people.add(person);
                    }
                    adapter = new CustomAdapter(c, people);
                    mListView.setAdapter(adapter);

                    new Handler().post(new Runnable() {
                        @Override
                        public void run() {
                            mListView.smoothScrollToPosition(people.size());
                                                            mListView.smoothScrollToPosition(people.indexOf(0));
                        }
                    });
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.d("mTAG", databaseError.getMessage());
                Toast.makeText(c, "ERROR " + databaseError.getMessage(), Toast.LENGTH_LONG).show();

            }
        });

        return people;
    }
}

CustomAdapter 类

public class CustomAdapter extends BaseAdapter implements Filterable {

    private static final String TAG = CustomAdapter.class.getSimpleName();
    Context c;
    ArrayList<Person> people;
    ArrayList<Person> mDataFiltered;
    ArrayList<Integer> selected;

    public CustomAdapter(Context c, ArrayList<Person> people) {
        this.c = c;
        this.people = people;
        this.mDataFiltered = people;
        selected = new ArrayList<>();
    }

    @Override
    public int getCount() {
        return people.size();
    }

    @Override
    public Object getItem(int position) {
        return people.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RecyclerView.ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(c).inflate(R.layout.one_line_list_item, parent, false);
        }

        CheckBox cbId = convertView.findViewById(R.id.cbid);
        TextView nameTextView = convertView.findViewById(R.id.name);
        TextView dateTextView = convertView.findViewById(R.id.date);
        TextView descriptionTextView = convertView.findViewById(R.id.description);

        final Person s = (Person) this.getItem(position);

        Log.i(TAG, "" + s.get_id());

        nameTextView.setText(s.getName());
        descriptionTextView.setText(s.getDetails());
        dateTextView.setText(s.getDay() + " " + s.getMonth() + " " + s.getYear());


        if (cbId != null ) {

            if (selected.contains(s.get_id())) {
                cbId.setChecked(true);
            } else {
                cbId.setChecked(false);
            }

            cbId.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(c, "" + s.get_id(), Toast.LENGTH_SHORT).show();
                }
            });

        }

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(c, s.getName(), Toast.LENGTH_SHORT).show();
            }
        });

        convertView.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {

                Log.i(TAG, "convertView.getTag --- " + v.getTag());
                int selected_id = s.get_id();
                if (selected.contains(selected_id)) {
                    selected.remove(selected.indexOf(selected_id));
                    v.setBackgroundColor(ContextCompat.getColor(v.getContext(), R.color.default_color));
                    v.setSelected(false);
                    Toast.makeText(v.getContext(), "CustomAdapter REMOVED: " + selected_id + " - " , Toast.LENGTH_SHORT).show();
                } else {
                    selected.add(selected_id);
                    v.setBackgroundColor(ContextCompat.getColor(v.getContext(), R.color.selected_color));
                    v.setSelected(true);
                    Toast.makeText(v.getContext(), "CustomAdapter ADDED: " + selected_id + " - " , Toast.LENGTH_SHORT).show();
                }

                return false;
            }
        });

        return convertView;
    }
}

人员类

public class Person {

    private String name;
    private String day;
    private String month;
    private String year;
    private String details;
    private int _id;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getDay() { return day; }
    public void setDay(String day) { this.day = day; }
    public String getMonth() { return month; }
    public void setMonth(String month) { this.month = month; }
    public String getYear() { return year; }
    public void setYear(String year) { this.year = year; }
    public String getDetails() { return details; }
    public void setDetails(String details) { this.details = details; }
    public int get_id() { return _id; }
    public void set_id(int _id) { this._id = _id; }
    public Person() { }
}

one_line_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="6dp"
    android:background="?android:attr/activatedBackgroundIndicator">

    <CheckBox
        android:id="@+id/cbid"
        android:layout_width="wrap_content"
        android:layout_height="?android:attr/listPreferredItemHeight"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="6dp"
        android:layout_marginLeft="26dp"
        android:layout_marginEnd="6dip"
        android:layout_marginRight="12dp"
        android:text="" />

    <TextView
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="26dp"
        android:layout_toStartOf="@id/cbid"
        android:layout_alignParentTop="true"
        android:lineHeight="18dp"
        android:maxLines="1"
        android:text="@string/name"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/date"
        android:layout_width="fill_parent"
        android:layout_height="18dp"
        android:layout_below="@+id/name"
        android:layout_toStartOf="@id/cbid"
        android:lineHeight="12dp"
        android:maxLines="1"
        android:text="@string/date"
        android:textSize="12sp" />

    <TextView
        android:id="@+id/description"
        android:layout_width="fill_parent"
        android:layout_height="18dp"
        android:layout_below="@id/date"
        android:layout_toStartOf="@id/cbid"
        android:lineHeight="18dp"
        android:maxLines="1"
        android:text="@string/additional_description"
        android:textSize="16sp" />

</RelativeLayout>

对不起,这段代码太长了,我只放了每个Class的必要部分,以使其尽可能清晰......

问题是:
单击列表中的任何checkbox 时,它似乎也在检查其他隐藏在视图中的内容。
我试图尽可能地隔离问题,但无法解决这个问题...
有什么想法为什么还要检查其他隐藏在视图中的项目??
它们以 8 的间隔被检查,并且当任何一个未被检查时也未被检查....

更新: 尝试在MainActivity 中实现此功能:

mListView.setLongClickable(true);
selected = new ArrayList<>();
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

        // int selected_id = s.get_id();
        int selected_id = position;
        if (selected.contains(selected_id)) {
            selected.remove(selected.indexOf(selected_id));
            Log.i(TAG, " -- remove -- " + parent.getChildAt(selected_id));
            parent.getChildAt(selected_id).setBackgroundColor(ContextCompat.getColor(context, R.color.default_color));
            //view.setBackgroundColor(ContextCompat.getColor(context, R.color.default_color));
            //view.setSelected(false);
            Toast.makeText(context, "MainAct REMOVED: " + selected_id + " - " , Toast.LENGTH_SHORT).show();
        } else {
            selected.add(selected_id);
            parent.getChildAt(selected_id).setBackgroundColor(ContextCompat.getColor(context, R.color.selected_color));
            Log.i(TAG, " -- add -- " + parent.getChildAt(selected_id));
            //view.setBackgroundColor(ContextCompat.getColor(context, R.color.selected_color));
            //view.setSelected(true);
            Toast.makeText(context, "MainAct ADDED: " + selected_id + " - " , Toast.LENGTH_SHORT).show();
        }
        return true;
    }
});

还是不行...:-(

【问题讨论】:

  • 您可以发布所有代码,并扩大赏金范围还是您已经找到解决方案?
  • @ChagaiFriedlander 我已将代码更改为完整的类代码,但找不到扩展赏金的方法,如果您知道方法请指导我...
  • 主类Activity的完整代码在哪里?你可以创建一个小项目并复制问题吗?把项目上传到github什么的,我可以帮你看看。我认为你可以再次提供赏金。
  • 免责声明:多年未接触 Android。 LongItemClick 事件不会通过RecyclerView/ListView 的项目传播吗?以this question 为例,他们似乎在这里使用了自定义RecyclerView.ViewHolder,以确保过滤掉那些不可见的。或者,您不能比较传递给事件的View v 并检查View 是否匹配convertView 或其中一个孩子,如果不匹配则忽略它?事件处理程序似乎并不关心它是否真的是被点击的项目。

标签: android firebase firebase-realtime-database checkbox


【解决方案1】:

尝试以下实现:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ....

    final Person s = (Person) this.getItem(position);

    if (selected.contains(s.get_id())) {
        cbId.setChecked(true);
    } else {
        cbId.setChecked(false);
    }

    ....

    cbId.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // update your model (or other business logic) based on isChecked

            int selected_id = s.get_id();
            if (selected.contains(selected_id)) {
                selected.remove(selected_id);
                Toast.makeText(c, "REMOVED: " + selected_id + " - " + isChecked, Toast.LENGTH_SHORT).show();
            } else {
                selected.add(selected_id);
                Toast.makeText(c, "ADDED: " + selected_id + " - " + isChecked, Toast.LENGTH_SHORT).show();
            }
        }
    });

    ....

    convertView.setOnLongClickListener(new View.OnLongClickListener() {

        @Override
        public boolean onLongClick(View v) {
            Toast.makeText(c, " -- onLongClick -- " + s.get_id() + " - " + s.getName(), Toast.LENGTH_SHORT).show();

            int selected_id = s.get_id();
            if (selected.contains(selected_id)) {
                selected.remove(selected_id);
            } else {
                selected.add(selected_id);
            }

            notifyDataSetChanged();

            return false;
        }
    });

    ....
}

【讨论】:

  • @Jadeye,你检查了吗?
猜你喜欢
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
  • 2018-05-23
  • 1970-01-01
相关资源
最近更新 更多