代码之家  ›  专栏  ›  技术社区  ›  user3282276

我在自定义视图中做错了什么导致它不能在可扩展列表视图中呈现(其他视图呈现良好)-android

  •  0
  • user3282276  · 技术社区  · 7 年前

    我试图在android中创建一个可扩展的listview,它使用一个自定义ui组件作为子视图,但实际上我很难让它呈现出来。当使用调试器跟踪我的应用程序时,我看到我的自定义ui对象被实例化并设置了数据,但是看起来它并没有添加到视图中,即使我在 getChildView() 是的。

    我的最终目标是创建一个自定义的ui元素, ServiceSelectionCheckbox ,我可以直接从布局托盘拖放。

    我试着直接为这个组件扩展xml,看看是不是我的xml出现了导致静默失败的问题,但看起来膨胀得很好。我还尝试创建了一个具有坚实背景的二级简单ui组件,以查看是否可以将其正确添加,这样做很好。这使我认为我的问题在于我的自定义ui组件, ServiceSelectionCheckbox.java 但我好像搞不懂那是什么问题。我的linter没有抛出错误,我的apk编译得很好。

    如果你能帮我指出正确的方向,我将不胜感激。

    main活动.java

    public class MainActivity extends AppCompatActivity {
    
    
        public HashMap<String, ArrayList<Pair<String, String>>> hashMapOfServices = new HashMap<>();
        public ArrayList<Pair<String, String>> aList;
        public ExpandableListView list;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            aList = new ArrayList<Pair<String, String>>();
            aList.add(new Pair<>("Men's Haircut", "50.00"));
            hashMapOfServices.put("Haircut", aList);
            list = (ExpandableListView) this.findViewById(R.id.list);
            list.setAdapter((ExpandableListAdapter) new ServiceExpandableListAdapter(this, this.hashMapOfServices));
    
    
        }
    }
    

    这是我的自定义适配器

    serviceExpandableListAdapter.java服务扩展列表适配器

    public class ServiceExpandableListAdapter extends BaseExpandableListAdapter {
        HashMap<String, ArrayList<Pair<String, String>>> hashmap;
        Context mContext;
        String[] selectedCategories;
    
        TextView price;
        ImageButton increment, decrement;
        ConstraintLayout lowerLayout;
        public static final ArrayList<String> POSSIBLECATEGORIES = new ArrayList<>(Collections.unmodifiableList(
                Arrays.asList("Barber", "Braids", "Children", "Color", "Esthetician",
                        "Eyebrows", "Eyelashes", "Hair Extensions", "Haircut", "Make-Up",
                        "Massage", "Nails", "Natural Hair", "Straightening", "Style", "Tanning", "Twists", "Waxing", "Weaves")));
    
        public ServiceExpandableListAdapter(Context context, HashMap<String, ArrayList<Pair<String, String>>> data) {
            mContext = context;
            hashmap = data;
            selectedCategories = data.keySet().toArray(new String[data.size()]);
    
        }
    
        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater infalater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = infalater.inflate(R.layout.group_heading, null);
            }
            TextView categoryName = (TextView) convertView.findViewById(R.id.service_category_tv);
            ImageView groupHolder = (ImageView) convertView.findViewById(R.id.groupholder);
            categoryName.setText(selectedCategories[groupPosition]);
            return convertView;
        }
    
        @Override
        public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.child_row, parent, false);
                //This one works properly
    //            convertView = inflater.inflate(R.layout.view, parent, false);
            }
    
            //return convertView;
    
            String category = selectedCategories[groupPosition];
            ServiceSelectionCheckbox checkbox = convertView.findViewById(R.id.service_selection_checkbox);
    
            String service = hashmap.get(category).get(childPosition).first;
            checkbox.setText(service);
    //        Pair of format <ServiceName, Price>
            Pair<String, String> testPair = new Pair<>(hashmap.get(selectedCategories[groupPosition]).get(childPosition).first, hashmap.get(selectedCategories[groupPosition]).get(childPosition).second);
            if (hashmap.containsValue(testPair)) {
                checkbox.setChecked(true);
            } else {
    
                checkbox.setChecked(false);
            }
    
            return convertView;
        }
    
    
        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return false;
        }
    
        @Override
        public boolean hasStableIds() {
            return true;
        }
    
        @Override
        public long getChildId(int groupPosition, int childPosition) {
    
            return childPosition;
        }
    
        @Override
        public long getGroupId(int groupPosition) {
    
            return groupPosition;
        }
    
        @Override
        public int getGroupCount() {
    
            return this.hashmap.keySet().size();
        }
    
        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return hashmap.get(selectedCategories[groupPosition]).get(childPosition);
        }
    
        @Override
        public Object getGroup(int groupPosition) {
            return hashmap.get(selectedCategories[groupPosition]);
    
        }
    
        @Override
        public int getChildrenCount(int groupPosition) {
            return hashmap.get(selectedCategories[groupPosition]).size();
    
        }
    
    }
    

    这是自定义ui元素的java文件。

    serviceselectioncheckbox.java服务选择复选框

    public class ServiceSelectionCheckbox extends View implements View.OnClickListener {
    
        private ConstraintLayout lowerLayout;
        private ImageButton increment, decrement;
        private float price;
        private int quantity;
        private TextView priceView, quantityView;
        private CheckBox checkBox;
        private boolean isQuantitySelectionVisible;
    
        public ServiceSelectionCheckbox(Context context, AttributeSet attrs, String serviceName, String price, int quantity) {
            super(context, attrs);
            this.isQuantitySelectionVisible = true;
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View v = inflater.inflate(R.layout.service_selection_checkbox_layout, null);
            priceView = (TextView) v.findViewById(R.id.service_selection_priceview);
            checkBox = (CheckBox) v.findViewById(R.id.ssc_checkbox);
            lowerLayout = (ConstraintLayout) v.findViewById(R.id.ssc_constraint_layout_quantity);
            quantityView = (TextView) v.findViewById(R.id.ssc_service_quantity_countview);
            increment = (ImageButton) v.findViewById(R.id.ssc_increase_service_count);
            decrement = (ImageButton) v.findViewById(R.id.ssc_decrease_service_count);
    
        }
    
        public ServiceSelectionCheckbox(Context context) {
            super(context);
            this.init();
        }
    
        public ServiceSelectionCheckbox(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.init();
        }
    
        private void init() {
    
            this.isQuantitySelectionVisible = false;
            LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View v = inflater.inflate(R.layout.service_selection_checkbox_layout, null);
            priceView = (TextView) v.findViewById(R.id.service_selection_priceview);
            checkBox = (CheckBox) v.findViewById(R.id.ssc_checkbox);
            this.setOnClickListener(this);
            lowerLayout = (ConstraintLayout) v.findViewById(R.id.ssc_constraint_layout_quantity);
            quantityView = (TextView) v.findViewById(R.id.ssc_service_quantity_countview);
            increment = (ImageButton) v.findViewById(R.id.ssc_increase_service_count);
            decrement = (ImageButton) v.findViewById(R.id.ssc_decrease_service_count);
        }
    
        public ServiceSelectionCheckbox(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            this.init();
        }
    
    
        @Override
        public void onClick(View view) {
            isQuantitySelectionVisible = !isQuantitySelectionVisible;
        }
    
        @Override
        public boolean performClick() {
            //set lowerlayout as visible based on visible variable
            if (this.isQuantitySelectionVisible) {
                lowerLayout.setVisibility(View.VISIBLE);
            } else {
                lowerLayout.setVisibility(View.GONE);
            }
    
            return super.performClick();
        }
    
    
        public void setPrice(float price) {
            this.price = price;
            this.priceView.setText(String.valueOf(price));
        }
    
        public void setQuantity(String quantity) {
            this.quantity = Integer.parseInt(quantity);
    
        }
    
        public void setChecked(boolean b) {
            this.checkBox.setChecked(b);
        }
    
        public void setText(String serviceName) {
            this.checkBox.setText(serviceName);
    
        }
    
    
    }
    

    这是相应的xml文件。

    组标题.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        android:orientation="horizontal">
    
        <TextView
            android:id="@+id/service_category_tv"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_weight="3"
            android:fontFamily="sans-serif-light"
            android:text="Categoy"
            android:textSize="22sp"
            android:background="@android:color/holo_orange_dark"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/groupholder"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    
        <ImageView
            android:id="@+id/groupholder"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_gravity="end"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginTop="8dp"
            android:foregroundGravity="right"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/service_category_tv"
            app:layout_constraintTop_toTopOf="parent" />
    
    </android.support.constraint.ConstraintLayout>
    

    这是我认为实际上给我带来麻烦的文件。

    子行.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:layout_editor_absoluteY="81dp">
    
    
        <com.example.gabriel.uitest.ServiceSelectionCheckbox
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/service_selection_checkbox"/>
    </android.support.constraint.ConstraintLayout>
    

    独立渲染后,将按预期创建视图。 服务选择复选框布局.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="visible"
        tools:layout_editor_absoluteY="81dp">
    
    
        <CheckBox
            android:id="@+id/ssc_checkbox"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginRight="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:checked="false"
            android:fontFamily="sans-serif-light"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:text="Service"
            android:textAllCaps="true"
            android:textSize="18sp"
            app:layout_constraintBottom_toTopOf="@+id/ssc_constraint_layout_quantity"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <TextView
            android:id="@+id/service_selection_priceview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:fontFamily="sans-serif-light"
            android:gravity="start|center"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            android:layout_marginRight="8dp" />
    
        <android.support.constraint.ConstraintLayout
            android:id="@+id/ssc_constraint_layout_quantity"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:visibility="visible"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/ssc_checkbox">
    
            <ImageButton
                android:id="@+id/ssc_decrease_service_count"
                android:layout_width="36dp"
                android:layout_height="36dp"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/ssc_service_quantity_countview"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
    
            <TextView
                android:id="@+id/ssc_service_quantity_countview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginTop="8dp"
                android:fontFamily="sans-serif-light"
                android:gravity="center"
                android:paddingEnd="8dp"
                android:paddingLeft="8dp"
                android:paddingRight="8dp"
                android:paddingStart="8dp"
                android:text="Quantity"
                android:textSize="18sp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toStartOf="@+id/ssc_increase_service_count"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toEndOf="@+id/ssc_decrease_service_count"
                app:layout_constraintTop_toTopOf="parent" />
    
            <ImageButton
                android:id="@+id/ssc_increase_service_count"
                android:layout_width="36dp"
                android:layout_height="36dp"
                android:layout_marginBottom="8dp"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toEndOf="@+id/ssc_service_quantity_countview"
                app:layout_constraintTop_toTopOf="parent" />
    
        </android.support.constraint.ConstraintLayout>
    </android.support.constraint.ConstraintLayout>
    

    这是我为前面提到的测试目的添加的测试视图组件,这个组件工作正常。 视图.xml

    <?xml version="1.0" encoding="utf-8"?>
    <View
        android:background="@color/colorAccent"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        xmlns:android="http://schemas.android.com/apk/res/android">
        </View>
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   pop    7 年前

    您需要定义自定义视图,如下所述。将其他代码添加到此视图中。我把它保持简单,这样你就更容易理解了。

    public class CustomView extends ConstraintLayout {
            public CustomView(Context context) {
                super(context);
                init();
            }
    
            public CustomView(Context context, AttributeSet attrs) {
                super(context, attrs);
                init();
            }
    
            public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
                init();
            }
    
            void init() {
                inflate(getContext(), R.layout. service_selection_checkbox_layout, this);
            }
        }
    

    除非需要,否则不要嵌套约束布局。在上面给出的带有一个constraintlayout本身的xml中,可以创建相同的ui。