Android - 在ExpandableListView的子视图中动态添加视图

时间:2015-12-03 15:24:00

标签: android android-arrayadapter android-view expandablelistview expandablelistadapter

我有ExpandableListView,我需要在Button点击时添加特定childView中放置按钮的新视图元素。

为此,我创建了一个TableLayout,其中放置了一个行,其中包含我需要在子视图中添加的视图元素。

这是我的孩子布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_height="match_parent"
                android:layout_width="wrap_content"
                android:paddingTop="5dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:textColor="@color/ColorPrimary"
        android:labelFor="@+id/time_stamp_view"
        android:textSize="20sp"
        android:text="@string/info_action_name"
        android:layout_marginRight="12dp"
        android:layout_marginLeft="12dp"
        android:layout_marginTop="24dp"
        android:id="@+id/action_text"/>

    <Spinner
        android:id="@+id/spinnerAction"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@+id/action_text"
        android:layout_marginRight="24dp"
        android:layout_alignBottom="@+id/action_text"
        android:layout_alignTop="@+id/action_text"/>

    <TableLayout
        android:id="@+id/tableTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_below="@+id/action_text"
        android:layout_alignStart="@+id/date_text"
        android:layout_marginBottom="8dp">

    </TableLayout>

    <!-- This imageview is the "button" to click -->

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/addTimeImageView"
        android:layout_below="@+id/tableTime"
        android:src="@drawable/ic_time_add"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/info_add_time_image"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:textColor="@color/ColorPrimary"
        android:textSize="20sp"
        android:text="@string/info_date1"
        android:layout_marginRight="12dp"
        android:layout_marginLeft="0dp"
        android:id="@+id/date_text"
        android:layout_below="@+id/addTimeImageView"
        android:layout_alignStart="@+id/date2_text"
        android:layout_marginTop="16dp"/>

</RelativeLayout>

这是我的自定义适配器:

    public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context context;
    private List<String> expandableListTitle;
    private HashMap<String, List<Action>> expandableListDetail;
    private LayoutInflater layoutInflater;
    private int mViewResourceId;
    private int k = 0;

    public ExpandableListAdapter(Context context, List<String> expandableListTitle,
                                 HashMap<String, List<Action>> expandableListDetail,
                                 int viewResourceId) {
        this.context = context;
        this.expandableListTitle = expandableListTitle;
        this.expandableListDetail = expandableListDetail;
        this.mViewResourceId = viewResourceId;
        this.layoutInflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

//    @Override
//    public  int getChildTypeCount(){
//        return 2;
//    }

//    @Override
//    public int getChildType(int groupPosition, int childPosition)
//    {
//        return expandableListDetail.get(this.expandableListTitle.get(groupPosition))
//                                   .get(childPosition).getId();
//    }

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

    @Override
    public View getChildView(final int listPosition, final int expandedListPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {

        final Action expandedListAction = (Action) getChild(listPosition, expandedListPosition);
        ViewHolder holder;
        ArrayAdapter<CharSequence> adapterAction = null;
        String[] timeSlot;

        if (convertView == null) {

            convertView = layoutInflater.inflate(mViewResourceId, parent, false);
            holder = new ViewHolder(convertView);

            convertView.setTag(holder);
        }

        holder = (ViewHolder)convertView.getTag();

        if(expandedListAction.getId() == 1)
            adapterAction = ArrayAdapter.createFromResource(context, R.array.actionId1, R.layout.spinner_item);
        else if(expandedListAction.getId() == 20)
            adapterAction = ArrayAdapter.createFromResource(context, R.array.actionId20, R.layout.spinner_item);

        if(adapterAction != null)
            adapterAction.setDropDownViewResource(R.layout.dropdown_list_spinner);

        holder.spinnerAction.setAdapter(adapterAction);

        ArrayAdapter<?> adapter = (ArrayAdapter<?>)holder.spinnerAction.getAdapter();
        for(Map.Entry<String, String[]> entry : expandedListAction.getActionToPerform().entrySet()){

            holder.spinnerAction.setSelection(((ArrayAdapter<CharSequence>)adapter).getPosition(entry.getKey()));
            timeSlot = entry.getValue();

             //Here i add row to table dinamically, according to data passed to adapter
             //why if add row when inflate layout, the adapter don't do that for each childView because convertview is not null for every child.
             // I can't override getChildTypeCount() because every view is different, not just few.
                for (int t = 0; t < timeSlot.length; t++) {


                    TableRow timeRow = new TableRow(context);

                    layoutInflater.inflate(R.layout.time_layout, timeRow, true);

                    EditText timeText = (EditText) timeRow.findViewById(R.id.timeText);
                    timeText.setText(timeSlot[t]);

                    holder.tableTime.addView(timeRow);
                }

        }
        }

        return convertView;
    }

    @Override
    public int getChildrenCount(int listPosition) {
        return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
                .size();
    }

    @Override
    public Object getGroup(int listPosition) {
        return this.expandableListTitle.get(listPosition);
    }

    @Override
    public int getGroupCount() {
        return this.expandableListTitle.size();
    }

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

    @Override
    public View getGroupView(int listPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
        String listTitle = (String) getGroup(listPosition);
        if (convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) this.context.
                    getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.list_group, null);
        }
        TextView listTitleTextView = (TextView) convertView
                .findViewById(R.id.listTitle);
        listTitleTextView.setText(listTitle);
        return convertView;
    }

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

    @Override
    public boolean isChildSelectable(int listPosition, int expandedListPosition) {
        return true;
    }

    static class ViewHolder {
        @Bind(R.id.spinnerAction)
        Spinner spinnerAction;
        @Bind(R.id.addTimeImageView)
        ImageView imageTimeView;
        @Bind(R.id.tableTime)
        TableLayout tableTime;

        public ViewHolder(View view){ButterKnife.bind(this, view);}
    }
}

这段代码工作得很好,但是我需要在Imageview上添加一个在表中添加新行的监听器。我尝试这样做(我在getView中添加了这段代码):

        holder.imageTimeView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            ViewGroup parent = (ViewGroup)v.getParent();
            Action azione1 = expandableListDetail.get(expandableListTitle.get(listPosition)).get(expandedListPosition);


            String actionType = null;
            for(Map.Entry<String, String[]> entry : azione1.getActionToPerform().entrySet()) {
                actionType = entry.getKey();
            }

                Action azione2 = new Action();
            azione2.setId(azione1.getId());
            azione2.setGroupAddress(azione1.getGroupAddress());
            azione2.setWeekDay(azione1.getWeekDay());

            Map<String, String[]> actionPerform = azione1.getActionToPerform();
            String[] time = actionPerform.get(actionType);
            String[] time2 = new String[time.length+1];

            time2[0] = "New time"+k;
            k++;
            for(int t=0; t<time.length; t++)
                time2[t+1] = time[t];

            Map<String, String[]> actionToPerform2 = new HashMap<>();
            actionToPerform2.put(actionType, time2);
            azione2.setActionToPerform(actionToPerform2);

      //When i call updateAction, i update the HashMap expandableListDetail passed from ModifyScenarioActivity when i set the adapter,
     //and then i call notifyDataSetChanged() on ExpandableListView adapter.

            ((ModifyScenarioActivity)context).updateAction(azione1, azione2, expandableListTitle.get(listPosition));

            TableLayout table = (TableLayout)parent.findViewById(R.id.tableTime);

            table.invalidate();
            table.refreshDrawableState();

        }
    });

此侦听器不起作用,因为它在表中添加了新行,但是相同的行被多次添加到其他子表的其他表中。 任何人都可以帮我处理这种情况吗?我不知道如何解决它。其他方法也很受欢迎。

修改

我添加了这个声明:

            if(holder.tableTime.getChildCount() < timeSlot.length) {
            holder.tableTime.removeAllViews();

//                for (int t = 0; t < timeSlot.length; t++) {
//
//                    TableRow timeRow = new TableRow(context);
//
//                    layoutInflater.inflate(R.layout.time_layout, timeRow, true);
//
//                    EditText timeText = (EditText) timeRow.findViewById(R.id.timeText);
//                    timeText.setText(timeSlot[t]);
//
//                    holder.tableTime.addView(timeRow);
//                }
            }

现在表格已刷新,但在其他子视图的另一个表格中,显示修改后的子视图的同一行,但我无法解释为什么在填充expandedListAction时使用getChild()进行调用在不同的listPosition和expandedListPosition上。我在调试器中发现数据没问题。

修改

我解决了每次调用getView时删除问题,表中的所有行以及再次添加resresreshed数据的问题。所以我问我是否可以提高滚动性能,也许每次都不删除和刷新表。 这是解决方案:

            holder.tableTime.removeAllViews();
        for (int t = 0; t < timeSlot.length; t++) {

            TableRow timeRow = new TableRow(context);

            layoutInflater.inflate(R.layout.time_layout, timeRow, true);

            EditText timeText = (EditText) timeRow.findViewById(R.id.timeText);
            timeText.setText(timeSlot[t]);

            holder.tableTime.addView(timeRow);
        }

0 个答案:

没有答案