将一系列重复的View组件提取到自己的View中的最佳方法是什么?

时间:2014-09-27 19:50:01

标签: android refactoring android-view android-ui

在我想创建的基本游戏应用程序中,我有一个菜单屏幕,其中包含一个框列表,每个框表示用户可以选择的级别。

这些框是RelativeLayout个,其中包含其他元素,例如TextView个,ProgressBarButton

由于我的布局中有很多这样的框,我想知道,有什么方法可以将每个框提取到自己的View中吗?我觉得这会让我的应用程序更干净,更有条理,更适合练习。

我查看了“创建自定义视图”,但它似乎包含了很多复杂的测量,我无法找到任何关于将现有视图包含到我的视图中的内容(例如,包括ProgressBar在我的自定义视图中。

这是一个截图,让您了解我正在做什么

Android Repeating View

1 个答案:

答案 0 :(得分:2)

自定义视图听起来像解决方案。我假设在常见的xml旁边你有一个共同的功能(当按下“go”时等)。

我采用的方法是提取公共布局并扩展相对布局,这将使该布局膨胀。

实际上在此之前已经回答过:Android: Custom view based on layout: how?

你可以使用android备注:http://developer.android.com/guide/topics/ui/custom-components.html#compound

编辑2 (替代方案,包含标记):

这种方式也从将公共布局提取到另一个xml开始。使用标记include(或merge标记),您可以将xml注入布局中的任何位置。 UI'组件'看起来是相同的,对于大多数可能提供满足您需求的答案。

更多关于: http://developer.android.com/training/improving-layouts/reusing-layouts.html

编辑1 (扩展视图,带示例代码):

第1步 - 定义视图的布局 - 这是常见的UI部分,只是一堆视图。

请注意,使用merge标记可以在布局层次结构中保存级别

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" 
    android:layout_width="wrap_content"
    android:background="@android:color/holo_green_dark"
    android:layout_height="wrap_content">

<TextView
    android:id="@+id/txtLevel"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:textSize="25sp"
    android:text="Level"/>

<ProgressBar
    android:id="@+id/progressBar"
    android:layout_centerHorizontal="true"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_below="@id/txtLevel"/>

<Button
    android:id="@+id/btnGo"
    android:layout_centerHorizontal="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/progressBar"
    android:text="Go"/>

</RelativeLayout>

第2步 - 创建一个扩展View的类(在本例中为RelativeLayout): 膨胀xml并设置一些onClick事件处理程序。

public class SampleCustomView extends RelativeLayout {

    public SampleCustomView(Context context, AttributeSet attr) {
        super(context, attr);

        // Adding the layout defined in the xml to my view
        this.addView(((LayoutInflater) this.getContext().getSystemService
                (Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.custom_view_layout, null));

        // Some sample event handling to the view
        ((Button)findViewById(R.id.btnGo)).setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v){
                ((Button)v).setText("Went");
            }
        });
    }
}

第3步 - 在应用程序的其他布局中使用视图

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <com.example.drorfichman.stuff.SampleCustomView
        android:id="@+id/myView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <com.example.drorfichman.stuff.SampleCustomView
        android:id="@+id/myView2"
        android:layout_marginTop="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

第4步 - 从activity / fragment

获取对视图的引用
public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        // This is one of the views
        SampleCustomView v = (SampleCustomView)findViewById(R.id.myView);
    }
}

结果(哦,恐怖)!

emulator