将Android布局与其所有者活动之外的逻辑相耦合

将Android布局与其所有者活动之外的逻辑相耦合,android,code-behind,Android,Code Behind,在开发一个中等复杂的Android应用程序时,我面临着一些复杂性。我正在搜索有关使用类似于的代码隐藏技术的可能性的信息,以便于Android软件的维护 目前(请突出显示任何错误),我发现为了创建包含额外对话框(例如,不属于主序列的对话框)的多步骤向导,我需要使用包含每个子视图作为子节点的ViewFlipper编写单个XML布局文件。今天,我发现了如何在视图间导航,而不是向前/向后(viewFlipper.setDisplayedChild(I)),从而可以访问额外的视图 现在,所有的Java代码

在开发一个中等复杂的Android应用程序时,我面临着一些复杂性。我正在搜索有关使用类似于
的代码隐藏技术的可能性的信息,以便于Android软件的维护

目前(请突出显示任何错误),我发现为了创建包含额外对话框(例如,不属于主序列的对话框)的多步骤向导,我需要使用包含每个子视图作为子节点的ViewFlipper编写单个XML布局文件。今天,我发现了如何在视图间导航,而不是向前/向后(
viewFlipper.setDisplayedChild(I)
),从而可以访问额外的视图

现在,所有的Java代码都包含在主
活动
类中,这看起来很糟糕。作为一名经验丰富的.NET开发人员,我学会了如何使用自定义控件将布局和业务逻辑包装到模块中

我知道在Android中,我可以以编程方式将视图定义为一个独立类,并以编程方式将其添加到主布局中,但是我想知道在Android中是否可以通过XML定义布局(以便于所见即所得的创建/编辑),并使用初始化逻辑在专用类中定义所有代码,按钮回调、异步任务等

我不确定这是可行的还是可以达成一个好的妥协

我读了这个问题,并没有消除我的疑虑

多谢各位

代码示例:

布局文件的摘录(我希望有4个向导步骤、一个帮助视图和一个EULA视图)

我想知道在Android中是否可以通过XML定义布局(更容易创建/编辑WYSIWYG),并在一个专用类中定义所有代码,包括初始化逻辑、按钮回调、异步任务等

对。它是创建自定义
视图的技术之一。例如,我有,可以直接在活动、对话框或自定义首选项中使用

我同意您的战术决定,即通过
可视翻转器实现向导--“墨菲的活动理论”请参阅


从长远来看,我认为正确的答案是有人(可能是我)提出了一个基于
片段
的向导模式,因为这会让您实现所需的解耦。

我认为这只是对代码进行一点重构的问题。。。太“私人”了吗?我的意思是,如果你分享你的代码,我们会有更多的想法来帮助你。这不是隐私问题,而是复杂性问题。无论如何,我将分享一点(仍在进行中)好的,我刚刚发现了“include”标记,以便在多视图布局中更容易地实现XML布局的模块化。重构代码可以/应该在不同的活动/片段中实现多个屏幕。这也会减少每个类的代码,并且对于向导来说应该可以很好地工作(特别是如果你只想向前和向后),我想你可以自定义在活动之间切换时发生的动画。不幸的是,这正是我不想要的。我知道如何以编程方式定义自定义视图,但我只想通过XML定义它们的外观以及它们在Java中的行为(单击、异步事件…)。一个XML+一个Java类就是我想要的。也许,如果我可以使用多个视图与动画,我可以实现一个伟大的目标result@djechelon:“我只想通过XML定义它们的外观以及它们在Java中的行为(单击,异步事件…)”--这正是我要说的。也许我应该看看ParcelHelper类+1:)你能描述一下你是如何制作这个调色器的吗?或者把我和一个教程联系起来?我认为关键在于你的ParcelHelper类,但我相信我需要一些指导。@djechelon:我在《忙碌的程序员指南》中介绍了高级Android开发的
ColorMixer
。其中一个知识共享许可的旧版本有以下章节:
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/view_phone"
    style="@android:style/Theme.Light.NoTitleBar"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <!-- First screen/welcome -->

    <LinearLayout
        android:id="@+id/view_phone_screen1"
        style="@android:style/Theme.Light.NoTitleBar"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:weightSum="100" >

        <TextView
            android:id="@+id/view_phone_screen1_lblChooseProvider"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical|center_horizontal"
            android:text="@string/view_phone_lblChooseProvider_1ststep"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <ImageButton
            android:id="@+id/view_phone_btnFrecciarossa"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:contentDescription="@string/provider_FRECCIAROSSA"
            android:gravity="center_vertical|clip_vertical"
            android:padding="10dp"
            android:src="@drawable/logo_frecciarossa"
            android:tag="@+id/provider_FRECCIAROSSA" />

        <ImageButton
            android:id="@+id/view_phone_btnItalo"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:contentDescription="@string/provider_ITALO"
            android:gravity="center_vertical|clip_vertical"
            android:padding="10dp"
            android:src="@drawable/logo_italo"
            android:tag="@+id/provider_ITALO" />
    </LinearLayout>


    <!-- Second screen - will need to do some asynchronous task -->
    <RelativeLayout
        android:id="@+id/view_phone_screen2"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <TextView
            android:id="@+id/view_phone_screen2_lblConnectingToWifi"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical|center_horizontal"
            android:text="@string/view_phone_lblConnectToWifi_2ndstep"
            android:textAppearance="?android:attr/textAppearanceLarge" />


        <TextView
            android:id="@+id/view_phone_step2_lblConnectedToWifi"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/imageView1"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="58dp"
            android:text="@string/view_phone_step2_connectingToWifi"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <TextView
            android:id="@+id/view_phone_step2_lblPhoneNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/editText1"
            android:layout_below="@+id/view_phone_step2_lblConnectedToWifi"
            android:layout_marginTop="51dp"
            android:text="@string/view_phone_step2_msgInputPhoneNumber"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
            android:id="@+id/view_phone_step2_lblUnableDetectPhoneNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="@string/view_phone_step2_msgUnableDetectPhoneNumber"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:visibility="invisible" />

        <Button
            android:id="@+id/view_phone_screen2_backward"
            style="@style/buttonBackward" />

        <Button
            android:id="@+id/view_phone_screen2_forward"
            style="@style/buttonForward_disabled"
            android:enabled="false" />

        <EditText
            android:id="@+id/view_phone_step2_txtPhoneNumber"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignRight="@+id/view_phone_step2_lblPhoneNumber"
            android:layout_below="@+id/view_phone_step2_lblPhoneNumber"
            android:inputType="phone"
            android:singleLine="true" >

            <requestFocus />
        </EditText>
    </RelativeLayout>

</ViewFlipper>
public class MyActivity extends Activity {
/** Called when the activity is first created. */

private final static String LOG_TAG = "LOG_TAG";
private int stepNumber;

@Override
public void onCreate(Bundle savedInstanceState) {
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    super.onCreate(savedInstanceState);

    this.stepNumber=1;

    setContentView(R.layout.view_phone);

    //This class wraps the click for the two buttons
    ProviderSelectionListener providerSelectionListener = new ProviderSelectionListener(this);
    this.findViewById(R.id.view_phone_btnFrecciarossa).setOnClickListener(providerSelectionListener);
    this.findViewById(R.id.view_phone_btnItalo).setOnClickListener(providerSelectionListener);
}

@Override
protected void onPause() {
    super.onPause();

    try {
        if (MyApplication.getPlatformManager() != null)
            MyApplication.getPlatformManager().onApplicationPause();
    } catch (MyCustomException e) {
        // WTF (Worse Than Failure!)
        Log.e(LOG_TAG, super.getString(R.string.zf_error_unknown_error_pauseactivity), e);
        e.printStackTrace();
    }
}

@Override
protected void onResume() {
    super.onResume();

    try {
        if (MyApplication.getPlatformManager() != null)
            MyApplication.getPlatformManager().onApplicationResume();
    } catch (MyCustomException e) {
        // WTF (Worse Than Failure!)
        Log.e(LOG_TAG, super.getString(R.string.zf_error_unknown_error_pauseactivity), e);
        e.printStackTrace();
    }
}

/*
 * SLIDE INIZIO
 */
protected void slideNext() {
    ViewFlipper vf = (ViewFlipper) findViewById(R.id.view_phone);

    vf.setOutAnimation(getApplicationContext(), R.anim.slide_out_left);
    vf.setInAnimation(getApplicationContext(), R.anim.slide_in_right);
    vf.showNext();

}

protected void slidePrevious() {
    ViewFlipper vf = (ViewFlipper) findViewById(R.id.view_phone);

    vf.setOutAnimation(getApplicationContext(), R.anim.slide_out_right);
    vf.setInAnimation(getApplicationContext(), R.anim.slide_in_left);
    vf.showPrevious();
}

/*
 * SLIDE FINE
 */

/*
 * STEP 1 INIZIO
 */
public void completeStep1(ISmsWifiProvider provider) {
    if (provider == null) {
        Log.e(LOG_TAG, "Provider nullo");
        return;
    }

    MyApplication.setAuthenticationProvider(provider);

    slideNext();

    initializeStep2();
}

public void returnToStep1() {
    MyApplication.setAuthenticationProvider(null);
    slidePrevious();
}

/*
 * STEP 1 FINE
 */

/*
 * STEP 2 INIZIO
 */

private void initializeStep2() {
    // Event handler
    Button backButton = (Button) findViewById(R.id.view_phone_screen2_backward), fwButton = (Button) findViewById(R.id.view_phone_screen2_forward);
    fwButton.setEnabled(false);
    backButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            returnToStep1();
        }
    });

}

/*
 * STEP 2 FINE
 */


@Override
public void onBackPressed() {
    // This will be called either automatically for you on 2.0
    // or later, or by the code above on earlier versions of the
    // platform.
    return;
}

}