代码之家  ›  专栏  ›  技术社区  ›  Ofek Pintok

可展开的ListView不会在单击时展开/折叠

  •  0
  • Ofek Pintok  · 技术社区  · 6 年前

    我不知道我错过了什么,虽然我遵循了一个教程,似乎我有一个问题,我无法跟踪。

    一些背景:

    首先,我的列表一开始没有孩子。用户创建组后,应用程序还会添加第一个子组。因为它没有任何子数据。这个 getChildView MyListAdapter )膨胀的观点有两种情况:第一个孩子的情况,和其他孩子的情况。第二种情况目前并不重要,因为我还没有给它下定义。回到第一个例子中,我创建了一个带有按钮的布局,我想将其显示为列表的第一行。

    问题是:

    enter image description here

    活动

    public class HomeScreen extends AppCompatActivity {
    
        private LinkedHashMap<Integer, WorkoutGroup> mySection = new LinkedHashMap<>();
        private ArrayList<WorkoutGroup> workoutList = new ArrayList<>();
        private ExpandableListView expandableListView;
        private MyListAdapter listAdapter;
    
        //two welcome messages that disappear after the insert of the first Group.
        private TextView noWorkoutsYet;
        private TextView welcomeTitle;
    
        //A layout that contains the table tabs of the log
        private ConstraintLayout tableTabs;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.home_screen_activity);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
    
    
            //Hide the text in the action bar
            getSupportActionBar().setDisplayShowTitleEnabled(false);
    
            //get reference to the welcome TextViews
            noWorkoutsYet = (TextView)findViewById(R.id.noWorkouts_tv);
            welcomeTitle = (TextView)findViewById(R.id.welcome_tv);
    
            //get reference to the table tabs layout
            tableTabs = (ConstraintLayout)findViewById(R.id.tableTabs);
    
            //get reference to the ExpandableListView
            expandableListView = (ExpandableListView) findViewById(R.id.myList);
    
            //create the adapter by passing your ArrayList data
            listAdapter = new MyListAdapter(HomeScreen.this, workoutList);
    
            //check if there is more then one workout in the list
            //if so, than update the layout
            if(listAdapter.getGroupCount()>0){
                setUpdatedView();
            }
    
            //attach the adapter to the list
            expandableListView.setAdapter(listAdapter);
    
            //expand all Groups
            expandAll();
    
            FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //get the last workout position and create a new workout
                    createNewWorkout(listAdapter.getGroupCount());
                }
            });
    
            //listener for group heading click
            //our group listener
                expandableListView.setOnGroupClickListener(new OnGroupClickListener() {
                @Override
                public boolean onGroupClick(ExpandableListView parent, View v,
                                            int groupPosition, long id) {
    
                    Log.d("onGroupClick:", "worked");
                    parent.expandGroup(groupPosition);
                    return false;
                }
            });
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds Groups to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_home_screen, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar Group clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
    
            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings) {
                return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    
        private void createNewWorkout(int mWorkoutPosition){
            //create a dialog that ask the date of the new workout from the user
            NewWorkoutGroupFragment newWorkDialog = new NewWorkoutGroupFragment();
            newWorkDialog.setStyle(DialogFragment.STYLE_NORMAL, R.style.CustomNewDialogFragment);
            newWorkDialog.setmWorkoutPosition(mWorkoutPosition);
            newWorkDialog.show(getFragmentManager(), "getDateFragment");
        }
    
        //method to expand all groups
        private void expandAll() {
            int count = listAdapter.getGroupCount();
            for (int i = 0; i < count; i++){
                expandableListView.expandGroup(i);
            }
        }
    
        //method to collapse all groups
        private void collapseAll() {
            int count = listAdapter.getGroupCount();
            for (int i = 0; i < count; i++){
                expandableListView.collapseGroup(i);
            }
        }
    
    
        //method that insert a workout to the list by last workout position and selected date
        public void buildWorkout(int mWorkoutPosition, String mDate) {
    
            //check the hash map if the workout group is already exists
            WorkoutGroup workoutGroup = mySection.get(mWorkoutPosition);
    
            //in case there is no such workout group, create a new one
            if (workoutGroup == null) {
                workoutGroup = new WorkoutGroup();
                //set new data as a group
                workoutGroup.setmWorkoutPosition(Integer.toString(mWorkoutPosition));
                workoutGroup.setmDate(mDate);
                //put the new workout group inside the hash map
                mySection.put(mWorkoutPosition, workoutGroup);
                //insert the new workout group to the list
                workoutList.add(workoutGroup);
                //update the visibility of some view items
                setUpdatedView();
    
                //The first child is a dummy item;
                //it has only a button that can create a new exercise
                ExerciseItem firstChild = new ExerciseItem();
                //add it as the first child
                addItemToExerciseList(mWorkoutPosition, firstChild);
            }else{
                Toast.makeText(this, R.string.error_workout_already_exists, Toast.LENGTH_SHORT).show();
            }
        }
    
        //This method insert an exercise to a list of exercises
        public void addItemToExerciseList(int mWorkoutPosition, ExerciseItem child) {
    
            WorkoutGroup workoutGroup = mySection.get(mWorkoutPosition);
            ArrayList<ExerciseItem> exerciseList = workoutGroup.getExerciseList();
    
            exerciseList.add(child);
    
            //update the changes
            workoutGroup.setExerciseList(exerciseList);
            listAdapter.notifyDataSetChanged();
    
            int groupPosition = workoutList.indexOf(workoutGroup);
    
            //collapse all groups
            collapseAll();
            //expand the group where item was just added
            expandableListView.expandGroup(groupPosition);
            //set the current group to be selected so that it becomes visible
            expandableListView.setSelectedGroup(groupPosition);
        }
    
        //update the new look of the screen after adding the first workout
        private void setUpdatedView(){
            welcomeTitle.setVisibility(View.INVISIBLE);
            noWorkoutsYet.setVisibility(View.INVISIBLE);
            tableTabs.setVisibility(View.VISIBLE);
        }
    
    }
    

    public class MyListAdapter extends BaseExpandableListAdapter {
    
        private ArrayList<WorkoutGroup> workoutList;
        private Context context;
    
        public MyListAdapter(Context context, ArrayList<WorkoutGroup> workoutList) {
            this.context = context;
            this.workoutList = workoutList;
        }
    
        /* Group Methods */
        @Override
        public View getGroupView(int groupPosition, boolean isLastChild, View view,
                                 ViewGroup parent) {
    
            WorkoutGroup workoutGroup = (WorkoutGroup) getGroup(groupPosition);
            if (view == null) {
                LayoutInflater inf = (LayoutInflater)
                        context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inf.inflate(R.layout.workout_heading, null);
            }
    
            TextView workoutPositionHeader = (TextView) view.findViewById(R.id.heading);
            int workoutPositionNum = Integer.valueOf(workoutGroup.getmWorkoutPosition());
            String workoutPosition = "#" + workoutPositionNum;
            workoutPositionHeader.setText(workoutPosition);
    
            TextView dateHeader = (TextView) view.findViewById(R.id.heading2);
            dateHeader.setText(workoutGroup.getmDate().trim());
    
            return view;
        }
    
        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }
    
        @Override
        public int getGroupCount() {
            return workoutList.size();
        }
    
        @Override
        public Object getGroup(int groupPosition) {
            return workoutList.get(groupPosition);
        }
    
        /* Child Methods */
        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
                                 View view, ViewGroup parent) {
    
            ExerciseItem exerciseItem = (ExerciseItem) getChild(groupPosition, childPosition);
            if (view == null) {
                LayoutInflater infalInflater = (LayoutInflater)
                        context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
                if (childPosition == 0) {
                    view = infalInflater.inflate(R.layout.button_exercise_row, null);
                } else {
                    view = infalInflater.inflate(R.layout.exercise_row, null);
                }
            }
    
            return view;
        }
    
        @Override
        public int getChildrenCount(int groupPosition) {
    
            ArrayList<ExerciseItem> exerciseList =
                    workoutList.get(groupPosition).getExerciseList();
            return exerciseList.size();
        }
    
    
        @Override
        public Object getChild(int groupPosition, int childPosition) {
            ArrayList<ExerciseItem> exerciseList =
                    workoutList.get(groupPosition).getExerciseList();
            return exerciseList.get(childPosition);
        }
    
        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }
    
        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }
    
        @Override
        public boolean hasStableIds() {
            return true;
        }
    }
    

    训练组

    public class WorkoutGroup {
    
    private String mWorkoutPosition = "";
    private String mDate = "";
    private ArrayList<ExerciseItem> exerciseList = new ArrayList<ExerciseItem>();
    
    public WorkoutGroup() {
    }
    
    public String getmWorkoutPosition() {
        return mWorkoutPosition;
    }
    
    public void setmWorkoutPosition(String mWorkoutPosition) {
        this.mWorkoutPosition = mWorkoutPosition;
    }
    
    public String getmDate() {
        return mDate;
    }
    
    public void setmDate(String mDate) {
        this.mDate = mDate;
    }
    
    public ArrayList<ExerciseItem> getExerciseList() {
        return exerciseList;
    }
    
    public void setExerciseList(ArrayList<ExerciseItem> exerciseList) {
        this.exerciseList = exerciseList;
    }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Ofek Pintok    6 年前

    我发现 android:descendantFocusability="blocksDescendants" 在xml文件中的子布局可以解决这个问题。