如何在自定义视图中添加视图?

11

我有一个类似的类,大约有10个

public class DataItemPlainView extends View{

    public DataItemPlainView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }}

现在我需要在这个视图中放置TextView、ImageView等控件。当我从其他地方调用它时,我希望获得我的customView。将一个视图设置为自定义布局也是一种情况。

谢谢

3个回答

11

您的自定义视图需要扩展ViewGroup或其它扩展了ViewGroup的类。例如,如果这些布局适合您的自定义视图所需完成的任务,您可以从RelativeLayoutLinearLayout中进行扩展。

请记住,即使是布局类也只是另一个View。它们仅仅具有将其他视图作为子视图添加的方法,并且具有递归测量和绘制其子视图的代码。


我需要返回一个视图以获取适配器的getView方法所需的适当视图。如果在这种情况下扩展ViewGroup,是否可以将其称为视图?(或者是View扩展ViewGroup),谢谢。 - ikbal
ViewGroup 绝对是 View 的扩展。 - Matt
我扩展了RelativeLayout,但是当我将视图添加到此自定义视图时,它不会出现,因此子视图未显示。 - user25

1

0
搞乱边距以实现绝对定位是错误的。如果你将来需要边距,这种方法就无法扩展。
从Android中偷取代码,进行修改,然后使用你的“未弃用”的绝对布局。
AbsoluteLayout被弃用是因为他们不想支持它,而不是因为它不起作用。
别管他们,他们的布局不能满足我们的需求,那么他们推荐什么?自定义视图。
所以这里有一个(重构后,不带样式(呕吐)支持):
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RemoteViews.RemoteView;


/**
 * A layout that lets you specify exact locations (x/y coordinates) of its
 * children. Absolute layouts are less flexible and harder to maintain than
 * other types of layouts without absolute positioning.
 *
 */
@RemoteView
public class DCAbsoluteLayout extends ViewGroup {
    int mPaddingLeft, mPaddingRight, mPaddingTop, mPaddingBottom;

    public DCAbsoluteLayout(Context context) {
        super(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int count = getChildCount();

        int maxHeight = 0;
        int maxWidth = 0;

        // Find out how big everyone wants to be
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        // Find rightmost and bottom-most child
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                int childRight;
                int childBottom;

                DCAbsoluteLayout.LayoutParams lp
                        = (DCAbsoluteLayout.LayoutParams) child.getLayoutParams();

                childRight = lp.x + child.getMeasuredWidth();
                childBottom = lp.y + child.getMeasuredHeight();

                maxWidth = Math.max(maxWidth, childRight);
                maxHeight = Math.max(maxHeight, childBottom);
            }
        }

        // Account for padding too
        maxWidth += mPaddingLeft + mPaddingRight;
        maxHeight += mPaddingTop + mPaddingBottom;

        // Check against minimum height and width
        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());

        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
                resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
    }

    /**
     * Returns a set of layout parameters with a width of
     * {@link ViewGroup.LayoutParams#WRAP_CONTENT},
     * a height of {@link ViewGroup.LayoutParams#WRAP_CONTENT}
     * and with the coordinates (0, 0).
     */
    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t,
            int r, int b) {
        int count = getChildCount();

        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != GONE) {

                DCAbsoluteLayout.LayoutParams lp =
                        (DCAbsoluteLayout.LayoutParams) child.getLayoutParams();

                int childLeft = mPaddingLeft + lp.x;
                int childTop = mPaddingTop + lp.y;
                child.layout(childLeft, childTop,
                        childLeft + child.getMeasuredWidth(),
                        childTop + child.getMeasuredHeight());

            }
        }
    }

    // Override to allow type-checking of LayoutParams.
    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof DCAbsoluteLayout.LayoutParams;
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new LayoutParams(p);
    }

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

    public static class LayoutParams extends ViewGroup.LayoutParams {
        /**
         * The horizontal, or X, location of the child within the view group.
         */
        public int x;
        /**
         * The vertical, or Y, location of the child within the view group.
         */
        public int y;

        /**
         * Creates a new set of layout parameters with the specified width,
         * height and location.
         *
         * @param width the width, either {@link #MATCH_PARENT},
                  {@link #WRAP_CONTENT} or a fixed size in pixels
         * @param height the height, either {@link #MATCH_PARENT},
                  {@link #WRAP_CONTENT} or a fixed size in pixels
         * @param x the X location of the child
         * @param y the Y location of the child
         */
        public LayoutParams(int width, int height, int x, int y) {
            super(width, height);
            this.x = x;
            this.y = y;
        }

        /**
         * {@inheritDoc}
         */
        public LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
        }

    }
}

一般来说,Android UI 是一个噩梦。考虑使用 webview 来完成整个项目。就系统的工作而言,“还好”,但是那个 UI 真是一团糟。

HTML 一直是样式和动态 UI 内容的首选。没有什么能与它相提并论,但自定义绘制的 UI(在性能方面)。


HTML支持绝对位置和多屏设置,那么为什么安卓不支持呢? - Hypersoft Systems

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接