在运行时创建的复合 Android 组件

发布于 2024-11-10 12:57:01 字数 3613 浏览 4 评论 0原文

问候。我正在开发一个项目,并认为我会汇总一个复合组件。我将它们放在 xml 中,并编写了一个扩展 LinearLayout 的新类。基本上,我在一个活动中需要大约五到六个。我想以编程方式在活动内部创建这些,因为我不知道在运行时之前需要多少个。此外,我还创建了一个 xml 文件来设置它们,但下面未包含该文件。我发现执行此操作的每种方法都存在问题。

以下是我创建的扩展 LinearLayout 的类内部的方法段:

public ExtendedLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    ...
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    ((Activity)getContext()).getLayoutInflater().inflate(R.layout.extended_linear_layout, this);
    ...
}

在 Activity 内部,这两个解决方案似乎最接近我正在寻找的解决方案。

不知道从哪里使用此方法获取属性:

ExtendedLinearLayout customViewClass = new ExtendedLinearLayout(this, attrs);
layout.addView(customViewClass)

不知道如何指定充气机应使用此方法的 ExtendedLinearLayout:

LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.extended_linear_layout, parent_layout);

我可能会选择使用 ListView - 但对于五到六个项目来说似乎有点过大。另外,根据之前与 Flex 的合作情况,这至少看起来是解决该问题的合理方案。

谢谢, 兰德尔

----------------更新--------------------

我已经尝试过下面讨论的方法。设置完所有内容后,我收到 InflationException: Binary XML file line #8: Error inflationing class。我感觉 xml 看起来很好。我可能感到困惑的一件事是在哪里调用充气机。现在,我在自定义类的 onFinishInflate() 以及 Activity 中调用充气器,如下所示:

public class ExtendedLinearLayout extends LinearLayout {
    ...
public ExtendedLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.extended_linear_layout, null);
        ...
    }
}

在 Activity 中:

public class TestActivity extends Activity {
    LinearLayout list;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        list = (LinearLayout) findViewById(R.id.simple_list);
        runTestCode();
    }
    private void runTestCode() {
        LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ExtendedLinearLayout layoutOne = 
                (ExtendedLinearLayout) inflater.inflate(R.layout.extended_linear_layout, list);
    }
}

谢谢,希望您有时间看一下。我喜欢通过在网上查资料来找出答案,但从昨天早上开始,这个已经让我煮了好几个小时了。我距离将其重构为 ListAdapter 大约还有 2 英寸。

----------------更新--------------------

这是xml文件

<?xml version="1.0" encoding="utf-8"?>
<com.anotherandroidblog.ExtendedLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    >
    <TextView
        android:id="@+id/text_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text=""
        ></TextView>
    <TextView
        android:id="@+id/text_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text=""
        ></TextView>
    <TextView
        android:id="@+id/text_three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        ></TextView>
</com.anotherandroidblog.ExtendedLinearLayout>

Greets. I'm working on a project and thought I would roll up a composite component. I laid them out in xml and wrote up a new class that extends LinearLayout. Basically, I will need about five or six of them in an Activity. I want to create these inside of an Activity programmatically because I don't know how many I will need before runtime. Also, I created an xml file to set them up which I haven't included below. I am having a problem with each of the methods I have found to do this.

Here are the method segments inside of the class I made that extends LinearLayout:

public ExtendedLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    ...
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    ((Activity)getContext()).getLayoutInflater().inflate(R.layout.extended_linear_layout, this);
    ...
}

And inside the Activity, these are the two solutions that appear to be the closest to what I'm looking for.

Don't know where to get the attrs from using this method:

ExtendedLinearLayout customViewClass = new ExtendedLinearLayout(this, attrs);
layout.addView(customViewClass)

Dont know how to specify that the inflater should use the ExtendedLinearLayout with this method:

LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.extended_linear_layout, parent_layout);

I will probably settle for using a ListView - but it seems a bit overkill for five to six items. Also, having worked with Flex before, this at least seems like a reasonable solution to the problem.

Thanks,
Randall

----------------UPDATE-------------------

I've tried the method as discussed below. Once I set everything up I'm getting an InflationException: Binary XML file line #8: Error inflating class. I feel like the xml looks just fine. One thing I may be confused about is where to call the inflater. Right now, I'm calling the inflater in onFinishInflate() of the custom class as well as in the Activity as follows:

public class ExtendedLinearLayout extends LinearLayout {
    ...
public ExtendedLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.extended_linear_layout, null);
        ...
    }
}

And in the activity:

public class TestActivity extends Activity {
    LinearLayout list;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        list = (LinearLayout) findViewById(R.id.simple_list);
        runTestCode();
    }
    private void runTestCode() {
        LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ExtendedLinearLayout layoutOne = 
                (ExtendedLinearLayout) inflater.inflate(R.layout.extended_linear_layout, list);
    }
}

Thanks and hope you've got time to take a look. I like to figure out stuff by digging around online but this one has had me cooked for a number of hours since yesterday morning. I'm about 2 inches away from just refactoring this into a ListAdapter.

----------------UPDATE-------------------

Here is the xml file

<?xml version="1.0" encoding="utf-8"?>
<com.anotherandroidblog.ExtendedLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    >
    <TextView
        android:id="@+id/text_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text=""
        ></TextView>
    <TextView
        android:id="@+id/text_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text=""
        ></TextView>
    <TextView
        android:id="@+id/text_three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        ></TextView>
</com.anotherandroidblog.ExtendedLinearLayout>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

早茶月光 2024-11-17 12:57:01

您需要在 XML 文件中使用完整的类名:不要将根元素 LinearLayout 设为 ExtendedLinearLayout 的完整类名(包括包名称)。然后 LayoutInflater 就会知道要做什么。

编辑:另外, attrs 选项实际上并不可行(或者至少我不这么认为)。我还没有找到一种方法来在运行时生成实际的 attrs 对象实例:没有公共构造函数,我希望这是框架在幕后所做的另一件事,但无法访问。

You need to use the full class name in the XML file: instead of making the root element LinearLayout make it the full class name for ExtendedLinearLayout (including package name). Then the LayoutInflater will know what to do.

EDIT: also, the attrs option isn't really workable (or at least I don't think so). I haven't found a way to generate at runtime the actually attrs object instance: there are no public constructors and I expect that's another one of the things the framework does under the hood that's just not accessible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文