The Green Bastard
The Green Bastard

Reputation: 1

ExpandableListView creating 2 children although im only populating 1 and only want 1?

I am trying to implement an ExpandableListView where each group has but one child under it. I have managed to populate the children correctly and implement a function to delete linked events from a calendar db. My problem is that each group displays the child i expect to see and one empty child fragment beneath it.

I tried hard coding to show only one child in my adapter but it just showed the blank child fragment instead of the populated data that i need.

I searched on here and did some tweaking to my xml files in regards to match_parent vs wrap_content but that didnt seem to make any difference at all.

I cant seem to figure out why its calling the blank fragment with each child item. When I run my delete code it will double my populated child as well until i refresh the list, if i run the delete code a third time it will add a third identically populated child until the list is refreshed, etc.

This is my Main Activity

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;
    }

}

This is my Adapter

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;
    }
}

And this is my event holder

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;
    }

}*

Any help would be greatly appreciated. A quick note, I'm relatively new to this so the dumber you can make it the easier it will be for me to follow.

Thank you in advance.

Upvotes: 0

Views: 40

Answers (2)

The Green Bastard
The Green Bastard

Reputation: 35

when i remove the +1 it does then show only one child. (this is the goal)

The problem now being it does not populate that child with any information, just the generic text from my layout file. That was the same result as when I tried to hardcode it to just 1.

why would my child populate when there are 2 views but now that i have eliminated the extra view it does not populate?

Edit : I had to move the end of my if statement in getChildView of the adapter to the end of my getChildView code that sets the textviews.I also got rid of the if(expandedListPosition<getChildrenCount(listPosition)-1) line that was in the same statement.

Thank you for your timely reply. I will mark it correct.

Upvotes: 0

Jujare Vinayak
Jujare Vinayak

Reputation: 123

Why are you returning dataSet.get(key).size()+1 in public int getChildrenCount(int listPosition) of ExpandableListEventAdapter when dataSet.get(key).size() is enough to return size. I mean why +1 added. Trying removing it.

Upvotes: 1

Related Questions