【问题标题】:Custom view made of multiple views由多个视图组成的自定义视图
【发布时间】:2012-10-19 16:12:28
【问题描述】:

我有一组我想始终一起使用的视图。这方面的一个例子可能是这样的:

<LinearLayout>
    <TextView />
    <EditView />
</LinearLayout>

文本视图是提示,编辑视图是答案。我想给这个组合起一个名字,并且能够使用这个名字把它弹出到 xml 中。我希望它是一个自定义视图,这样我就可以把它很好地放在一个类中,并为它创建各种实用函数。有什么办法可以做到吗?我知道我可以继承 LinearLayout 并在 java 代码中动态创建子级,但这使我无法通过 xml 轻松进行更改。有更好的路线吗?

是的,我也有一些我想做的地方,而不仅仅是提示。

【问题讨论】:

  • 无耻的自我推销,但可能是相关的 - stackoverflow.com/questions/11722340/edittext-on-demand-widget
  • 你读过Android关于设计Custom Components的文章吗?
  • 是的,我有 Sam,过去我自己编写了 3 个自定义视图(一个用于显示相机的 Camera View,一个用于将 Web 上的图像直接下载到一个 imageview 中的 UrlImageView,以及一个DragAndDrop 图像布局在 AbsoluteLayout 之上)。但是该页面中的所有内容都没有向您展示如何在 xml 中定义带有子视图的小部件——它们都是在 Java 中完成的。我希望避免这种情况。

标签: android android-layout


【解决方案1】:

此示例适用于水平数字选择器小部件,但概念相同。

首先为您的自定义组件创建 XML 布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

   <Button
       android:id="@+id/btn_minus"
       android:layout_width="50dp"
       android:layout_height="wrap_content"
       android:text="-" />

   <EditText
       android:id="@+id/edit_text"
       android:layout_width="75dp"
       android:layout_height="wrap_content"
       android:inputType="number"
       android:gravity="center"
       android:focusable="false"
       android:text="0" />

   <Button
       android:id="@+id/btn_plus"
       android:layout_width="50dp"
       android:layout_height="wrap_content"
       android:text="+" />
</LinearLayout>

然后创建java类

public class HorizontalNumberPicker extends LinearLayout {
    public HorizontalNumberPicker(Context context, AttributeSet attrs) {
         super(context, attrs);
         LayoutInflater inflater = LayoutInflater.from(context);
         inflater.inflate(R.layout.horizontal_number_picker, this);
     }
 }

向那个 java 类添加你需要的任何逻辑,然后你可以像这样在你的 XML 布局中包含自定义组件:

<com.example.HorizontalNumberPicker
     android:id ="@+id/horizontal_number_picker"
     android:layout_width ="wrap_content"
     android:layout_height ="wrap_content" />


查看此链接了解更多信息:http://developer.android.com/guide/topics/ui/custom-components.html#compound

【讨论】:

  • 我试过这个,让 Android Studio 先把它转换成 Kotlin。在构造函数中,我使用“this”作为上下文,但我不知道 AttributeSet。刚刚学习 Android(来自 iOS 开发者背景)。
  • 如果我理解正确的话,HorizontalNumberPicker 有两个LinearLayouts?它本身是一,它也在构造函数中膨胀一。好像一个太多了。
  • @rozina 我认为您可以在自定义组件的布局文件中使用 标记代替 LinearLayout。这将消除额外的布局。
【解决方案2】:

为此目的使用Compound controls。有很多关于它的示例和教程。祝你好运)

【讨论】:

    【解决方案3】:

    将该 XML 放入布局 XML 文件中,并在需要时使用充气器为视图充气。

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.some_id, parent, false);
    

    一旦有了视图,您就可以编写一个实用程序类来接受该视图并对其执行操作。使用findViewById() 检索文本和编辑视图,或使用ViewHolder pattern 存储对其他视图的引用

    【讨论】:

    • 嗯。如果我要在从布局派生的类的构造函数中执行此操作(例如 LinearLayout),我可以在父 xml 中引用它,并将其作为父级传递。如果子视图的顶级 xml 是一个合并标记,它将消除我们需要在其中塞入的额外布局。而且我也可以使用 ViewHolder 模式来提高效率,但是持有人本身就是一个视图,所以我可以避免做所有丑陋的标签。我认为这有潜力,我今天晚些时候回家后会测试它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多