首页 > 解决方案 > ExpandableListView 创建 2 个孩子虽然我只填充 1 并且只想要 1?

问题描述

我正在尝试实现一个 ExpandableListView ,其中每个组只有一个孩子。我已经设法正确填充孩子并实现了从日历数据库中删除链接事件的功能。我的问题是每个组都显示我希望看到的孩子和它下面的一个空的孩子片段。

我尝试了硬编码以在我的适配器中只显示一个孩子,但它只显示了空白的孩子片段,而不是我需要的填充数据。

我在这里搜索并针对 match_parent 与 wrap_content 对我的 xml 文件进行了一些调整,但这似乎根本没有任何区别。

我似乎无法弄清楚为什么它用每个子项调用空白片段。当我运行我的删除代码时,它也会使我填充的孩子翻倍,直到我刷新列表,如果我第三次运行删除代码,它将添加第三个相同填充的孩子,直到刷新列表,等等。

这是我的主要活动

public class MainActivityCalendarManager extends AppCompatActivity {
    Context context;
    View parentView;
    ArrayList<String> titles;
    ArrayList<Date> dates;
    TreeMap<Date,ArrayList<CalendarManagerEvent>> dataSet;
    ExpandableListEventAdapter eveAdpt;
    ExpandableListView listView;
    SwipeRefreshLayout swipeRefreshLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cal_mgr_activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        //Set the drawer icon
        final ActionBar actionBar = getSupportActionBar();
        actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_left);
        actionBar.setDisplayHomeAsUpEnabled(true);
        parentView = findViewById(android.R.id.content);
        dates = new ArrayList<>();
        titles = new ArrayList<>();
        CoordinatorLayout layout = (CoordinatorLayout) findViewById(R.id.cal_mgr_activity_main);
        getLayoutInflater().inflate(R.layout.cal_mgr_content_main, layout);
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.cal_mgr_swipe_refresh);
        context = this;
        getDataFromCalendarTable();
        listView = (ExpandableListView) findViewById(R.id.elv_main);
        dataSet = new TreeMap<>();
        dataSet = getDataFromEventTable();
        eveAdpt = new ExpandableListEventAdapter(context,dates, dataSet,titles);
        listView.setAdapter(eveAdpt);


        listView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {

                return false;
            }
        });

        listView.setOnChildClickListener((ExpandableListView.OnChildClickListener) (parent, v, groupPosition, childPosition, id) -> {

            TextView uid = (TextView) v.findViewById(R.id.tv_uid);
            String mUid = uid.getText().toString();
            deleteEvent(Long.parseLong(mUid));
           // updateListView();
            return true;
        });


        swipeRefreshLayout.setOnRefreshListener(() -> {
            updateListView();
            Log.i("refresh", "Layout Refreshed");
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

    }

    public void getSnackbar(View view, String text)
    {
        Snackbar.make(view, text, Snackbar.LENGTH_LONG).setAction("Action", null).show();
    }

    public void updateListView()
    {
         dataSet = getDataFromEventTable();
         eveAdpt.update(dates,dataSet);
        eveAdpt.notifyDataSetChanged();
        swipeRefreshLayout.setRefreshing(true);
    }

    // this reads the data from the calendar table
    public void getDataFromCalendarTable() {
        Cursor cur;
        ContentResolver cr = getContentResolver();

        String[] mProjection =
                {
                        CalendarContract.Calendars.ALLOWED_ATTENDEE_TYPES,
                        CalendarContract.Calendars.ACCOUNT_NAME,
                        CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
                        CalendarContract.Calendars.CALENDAR_LOCATION,
                        CalendarContract.Calendars.CALENDAR_TIME_ZONE,
                        CalendarContract.Calendars._ID
                };
        final SharedPreferences mSharedPreference= PreferenceManager.getDefaultSharedPreferences(context);
        Uri uri = CalendarContract.Calendars.CONTENT_URI;
        String selection = "((" + CalendarContract.Calendars.ACCOUNT_NAME + " = ?) AND ("
                + CalendarContract.Calendars.ACCOUNT_TYPE + " = ?) AND ("
                + CalendarContract.Calendars.OWNER_ACCOUNT + " = ?))";
        String[] selectionArgs = new String[]{mSharedPreference.getString("account_name",""), mSharedPreference.getString("account_type",""),
                mSharedPreference.getString("owner_account","")};

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CALENDAR},0);
        }
        cur = cr.query(uri, mProjection, selection, selectionArgs, null);

        while (cur.moveToNext()) {
            String displayName = cur.getString(cur.getColumnIndex(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME));
            String accountName = cur.getString(cur.getColumnIndex(CalendarContract.Calendars.ACCOUNT_NAME));
            String ID = cur.getString(cur.getColumnIndex(CalendarContract.Calendars._ID));
        }
        cur.close();
    }

    // this is the main array for the information table contained in dataset
    public TreeMap<Date,ArrayList<CalendarManagerEvent>> getDataFromEventTable() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CALENDAR}, 0);
        }
        Cursor cur;
        ContentResolver cr = getContentResolver();

        String[] mProjection =
                {
                        "_id",
                        CalendarContract.Events.CALENDAR_ID,
                        CalendarContract.Events.TITLE,
                        CalendarContract.Events.DTSTART,
                        CalendarContract.Events.DTEND,
                        CalendarContract.Events.DESCRIPTION,
                        CalendarContract.Events._ID
                };

        Uri uri = CalendarContract.Events.CONTENT_URI;
        String selection = CalendarContract.Events.CALENDAR_ID + " = ? ";
        // this sets every calendar to the same ID so I dont end up with 300
        // individual calendars (Calendar In Use Is Local#16)
        String[] selectionArgs = new String[]{"16"};

        cur = cr.query(uri, mProjection, selection, selectionArgs, null);

        while (cur.moveToNext()) {
            if (Integer.parseInt(cur.getString(cur.getColumnIndex(CalendarContract.Events.CALENDAR_ID))) == 16) {
                try {
                    int id = Integer.parseInt(cur.getString(cur.getColumnIndex(CalendarContract.Events.CALENDAR_ID)));
                    String title = cur.getString(cur.getColumnIndex(CalendarContract.Events.TITLE));
                    long dtstart = Long.parseLong(cur.getString(cur.getColumnIndex(CalendarContract.Events.DTSTART)));
                    long dtend = Long.parseLong(cur.getString(cur.getColumnIndex(CalendarContract.Events.DTEND)));
                    String desc = cur.getString(cur.getColumnIndex(CalendarContract.Events.DESCRIPTION));
                    String eventID = cur.getString(cur.getColumnIndex(CalendarContract.Events._ID));

                    // functions related to getting the date formatted correctly
                    Date testDate = new Date(dtstart);
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(testDate);
                    cal.set(Calendar.HOUR_OF_DAY,0);
                    cal.set(Calendar.MINUTE,0);
                    cal.set(Calendar.SECOND,0);
                    Date inputDate = cal.getTime();
                    // end date related code
                    CalendarManagerEvent calendarManagerEvent = new CalendarManagerEvent(id, title, desc, dtstart, dtend, eventID);
                    if(dataSet.get(inputDate)== null)
                    {
                        ArrayList<CalendarManagerEvent> calendarManagerEvents = new ArrayList<>();
                        calendarManagerEvents.add(calendarManagerEvent);
                        dataSet.put(inputDate, calendarManagerEvents);
                        dates.add(inputDate);
                        titles.add(title);
                    }
                    else
                    {
                        ArrayList<CalendarManagerEvent> datesArrayList = dataSet.get(inputDate);
                        boolean unique = true;
                        for(CalendarManagerEvent e : datesArrayList)
                        {
                            if (e.getUid().equals(calendarManagerEvent.getUid())) {
                                unique = false;
                                break;
                            }
                        }
                        if(unique) {
                            datesArrayList.add(calendarManagerEvent);
                            dataSet.remove(inputDate);
                            titles.remove(title);
                            dataSet.put(inputDate, datesArrayList);
                            titles.add(title);
                        }
                    }
                }
                // just error messages
                catch(Exception e)
                {
                    Log.e("Error", e.getMessage());
                    Log.e("start time",cur.getString(cur.getColumnIndex(CalendarContract.Events.DTSTART)));
                    Log.e("end time",cur.getString(cur.getColumnIndex(CalendarContract.Events.DTEND)));
                }
            }
        }
        cur.close();
        // bundle everything up into the dataset
        return dataSet;
    }


    private void deleteEvent(long eventID) {
        Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
        int rows = getContentResolver().delete(deleteUri, null, null);
        Log.i("Calendar", "Rows deleted: " + rows);
        eveAdpt.notifyDataSetChanged();
    }


    @Override
    public boolean onSupportNavigateUp() {
        finish();
        return true;
    }

}

这是我的适配器

public class ExpandableListEventAdapter extends BaseExpandableListAdapter {
    private final Context context;
    private ArrayList<Date> dates;
    private ArrayList<String> titles;
    private TreeMap<Date,ArrayList<CalendarManagerEvent>> dataSet;
    private SparseBooleanArray mSelectedItemsIds;
    LayoutInflater inflater;
    private boolean isLastChild = true;

    ListPopupWindow listPopupWindow;
    String[] uid = {"Delete"};

    ExpandableListEventAdapter(Context context) {
        inflater = LayoutInflater.from(context);
        this.context = context;
    }



    public ExpandableListEventAdapter(Context context, ArrayList<Date> dates, TreeMap<Date,ArrayList<CalendarManagerEvent>> events, ArrayList<String> titles)
    {
        this.context = context;
        this.dates = dates;
        this.dataSet = events;
        this.titles = titles;
    }

    @Override
    public int getGroupCount() {

        return this.dates.size();
    }

    @Override
    public int getChildrenCount(int listPosition) {
        Date key = this.dates.get(listPosition);
        return this.dataSet.get(key).size()+1;
    }

    @Override
    public Object getGroup(int listPosition) {

        return this.dates.get(listPosition);
    }

    @Override
    public Object getChild(int listPosition, int expandedListPosition)
    {
        return this.dataSet.get(this.dates.get(listPosition)).get(expandedListPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int listPosition, int expandedListPostion) {
        return expandedListPostion;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    // This is just for the first parent expandable list view item
    @Override
    public View getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        Date date = dates.get(listPosition);
        String title = titles.get(listPosition);
        if(convertView == null){
            LayoutInflater layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.cal_mgr_groupview_listitem,null);
        }
        TextView dateView = (TextView) convertView.findViewById(R.id.tv_groupView_date);
        TextView titleView = (TextView) convertView.findViewById(R.id.tv_main_title);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        dateView.setText(dateFormat.format(date.getTime()));
        titleView.setText(title);

        return convertView;
    }

    // this sets the child items on expandable list view item
    @Override
    public View getChildView(int listPosition, int expandedListPosition, boolean isLastChild, View itemView, ViewGroup parent) {
        TextView desc, uid;
        //create the list item

        if(itemView == null){
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            itemView = inflater.inflate(R.layout.cal_mgr_childview_listitem, parent, false);
        }

        if(expandedListPosition<getChildrenCount(listPosition)-1) {
            final CalendarManagerEvent currentCalendarManagerEvent = (CalendarManagerEvent) getChild(listPosition,expandedListPosition);
            // declare the textviews
            desc = (TextView) itemView.findViewById(R.id.tv_groupView_desc);
            uid = (TextView) itemView.findViewById(R.id.tv_uid);
            // set the text in above views
            desc.setText(currentCalendarManagerEvent.getDesc());
            uid.setText(currentCalendarManagerEvent.getUid());

        }

        return itemView;
    }



    public void toggleSelection(int position) {
        selectView(position, !mSelectedItemsIds.get(position));
    }

    public void removeSelection() {
        mSelectedItemsIds = new SparseBooleanArray();
        notifyDataSetChanged();
    }

    public void selectView(int position, boolean value) {
        if (value)
            mSelectedItemsIds.put(position, value);
        else
            mSelectedItemsIds.delete(position);
        notifyDataSetChanged();
    }

    public void update(ArrayList<Date> dates,TreeMap<Date,ArrayList<CalendarManagerEvent>> events){
        this.dates = dates;
        this.dataSet = events;
        notifyDataSetChanged();
    }

    private class ViewHolder {
        TextView title;
        TextView date;
        TextView desc;
        TextView uid;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }
}

这是我的活动持有人

public class CalendarManagerEvent {
    private String eventID;
    private String title;
    private String desc;

    public CalendarManagerEvent(int id, String title, String desc, long dtstart, long dtend, String eventID)
    {  // This is the model for the array that is made for listview items
        this.title = title;
        this.desc = desc;
        this.eventID = eventID;
    }

    public String getTitle(){
        return title;
    }

    public void setTitle(String title){
        this.title = title;
    }

    public String getDesc() {
        return desc;
    }


    public String getUid()
    {
        return eventID;
    }

}*

任何帮助将不胜感激。快速说明,我对此比较陌生,所以你越笨,我就越容易理解。

先感谢您。

标签: javaandroidexpandablelistviewandroid-adapter

解决方案


dataSet.get(key).size()足以返回大小时,为什么要在ExpandableListEventAdapterpublic int getChildrenCount(int listPosition)中返回dataSet.get(key).size()+1 。我的意思是为什么添加了+1。试图删除它。


推荐阅读