【问题标题】:How to create a custom dialog with Accept/Cancel and data from the MainActivity?如何使用接受/取消和 MainActivity 中的数据创建自定义对话框?
【发布时间】:2014-12-16 22:13:32
【问题描述】:

我想从我的 MainActivity 创建一个对话框,带有一个接受和取消按钮,它有一个自定义视图(我已经创建了它,一个布局)。在那个自定义对话框中,我必须用我给他的 ArrayList 填充 2 个微调器(顺便说一句,我不知道该怎么做),我希望用户从这两个微调器中选择选项,使它们成为点击“接受”所必需的,当用户点击“接受”时,我必须将他的创作添加到我的数据库中。

我完全迷路了,我只创建了这个布局,那是对话框的视图,我不知道该怎么做...有人请帮助我,这非常令人沮丧=(

这是对话框的 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="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/dialog_evento"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Spinner
        android:id="@+id/spinnerEvento"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/dialog_accion"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Spinner
        android:id="@+id/spinnerAccion"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

这是集体诉讼:

package com.nahue.actions;

public class Action {

  //declaración de atributos
  private int Id;
  public int getId() {
    return Id;
}

public void setId(int id) {
    Id = id;
}

public int getIdAccion() {
    return IdAccion;
}

public void setIdAccion(int idAccion) {
    IdAccion = idAccion;
}

public int getIdEvento() {
    return IdEvento;
}

public void setIdEvento(int idEvento) {
    IdEvento = idEvento;
}

public boolean getActiva() {
    return Activa;
}

public void setActiva(boolean activa) {
    Activa = activa;
}

private int IdAccion;
  private int IdEvento;
  private boolean Activa;

  //declaración de constructor
  public Action(int Id, int IdAccion, int IdEvento, boolean Activa){
    this.Id = Id; //Autonumérico
    this.IdAccion = IdAccion;
    this.IdEvento = IdEvento;
    this.Activa = Activa;
  }
}

这是 DialogActions 类:

package com.nahue.actions;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.os.Parcelable;
import android.app.DialogFragment;
// ...
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import com.nahue.actions.R;

public class DialogActions extends DialogFragment
{    



    private Button cancelButton;
    private Button confirmButton;
    private DialogActions DialogListener;
    private Spinner spinnerAccion;
    private Spinner spinnerEvento;

    public DialogActions()
    {
        // Empty constructor required for DialogFragment
    }

    //This is how you can supply your fragment with information
    public static DialogActions newInstance(ArrayList<Action> ListaActions)
    {
        DialogActions myDialog = new DialogActions();
        Bundle args = new Bundle();
        args.putParcelableArrayList("ListaActions", ArrayList<Action> ListaActions);//Errors: ArrayList and Action cannot be resolved into variables
        myDialog.setArguments(args);
        return myDialog;
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NO_TITLE, 0); // remove title from dialogfragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.dialog_actions, container);

        //DECLARO LOS ELEMENTOS EN EL LAYOUT


        //Setup cancel button listener
        cancelButton = (Button) view.findViewById(R.id.cancelButton);
        cancelButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                getDialog().dismiss();
            }
        });

        //Setup confirm button listener
        confirmButton = (Button) view.findViewById(R.id.confirmButton);
        confirmButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                //AGREGAR A LA BD
                getDialog().dismiss();
            }
        });
        return view;
    }

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        if (activity instanceof DialogActions) //Error: Incompatible conditional operand types Activity and DialogActions
        {
            DialogListener = (DialogActions) activity; //Error: "Cannot cast from Activity to DialogActions"
        }
        else
        {
            throw new ClassCastException(activity.toString() + " must implement StartProfileDialog.StartProfileListener");
        }
    }
}

【问题讨论】:

  • 好的,我知道你做错了什么。您缺少界面。仔细看看 StartProfilerListener,它与 StartProfileDialog 是分开的。你会想做一些类似 public interface DialogActionsListener { void doAction(int spinnerVal 1, int spinnerVal 2); } 然后是私有的 DialogActionsListener dialogListener;
  • 是的!你是对的,固定的。现在我唯一需要知道的是如何使 Actions 可打包,我无法理解你给我的链接:S
  • 您需要让您的 Actions 对象实现 Parcelable,然后扩展 ArrayList 以创建一个也实现 Parcelable 的自定义 ActionList。然后您应该能够在您的应用程序中使用 Parcelable 功能。我实际上还没有完成任何 Parcelable 编码,所以在你尝试了一段时间之后,你可能会想提出一个新问题。
  • 好的,我会提出一个新问题。无论如何,非常感谢你,你帮了我很多! :D

标签: android database dialog android-alertdialog


【解决方案1】:

有很多方法可以做到这一点,每种方法都有自己的优缺点。我目前的做法是让每个自定义对话框成为 DialogFragment。

这是课程

import android.app.Activity;
import android.os.Bundle;
import android.app.DialogFragment;
// ...
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;


public class StartProfileDialog extends DialogFragment
{    

    public interface StartProfileListener
    {
        void onStartProfile();
    }

    private Button cancelButton;
    private Button confirmButton;
    private StartProfileListener startProfileListener;
    private String profileName;

    public StartProfileDialog()
    {
        // Empty constructor required for DialogFragment
    }

    //This is how you can supply your fragment with information
    public static StartProfileDialog newInstance(String profileName)
    {
        StartProfileDialog myDialog = new StartProfileDialog();
        Bundle args = new Bundle();
        args.putString("profileName", profileName);
        myDialog.setArguments(args);
        return myDialog;
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NO_TITLE, 0); // remove title from dialogfragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.fragment_start_profile_dialog, container);
        profileName = getArguments().getString("profileName"); 

        //Set Text in center
        TextView startProfileMessage = (TextView) view.findViewById(R.id.startProfileMessage);
        String startProfileMessageContent = getString(R.string.start_profile_prefix) + " " + profileName
            + " " + getString(R.string.start_profile_suffix);
        startProfileMessage.setText(startProfileMessageContent);

        //Setup cancel button listener
        cancelButton = (Button) view.findViewById(R.id.cancelButton);
        cancelButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                getDialog().dismiss();
            }
        });

        //Setup confirm button listener
        confirmButton = (Button) view.findViewById(R.id.confirmButton);
        confirmButton.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                startProfileListener.onStartProfile();
                getDialog().dismiss();
            }
        });
        return view;
    }

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        if (activity instanceof StartProfileListener)
        {
            startProfileListener = (StartProfileListener) activity;
        }
        else
        {
            throw new ClassCastException(activity.toString() + " must implement StartProfileDialog.StartProfileListener");
        }
    }
}

还有 XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/startProfileDialogTitle"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/start_profile"
        android:textSize="24sp"
        android:layout_gravity="center"" />
    <TextView
        android:id="@+id/startProfileMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="horizontal"
    />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="horizontal"
    >
        <Button
            android:id="@+id/cancelButton"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/cancel"
        />
        <Button
            android:id="@+id/confirmButton"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/confirm"
        />
    </LinearLayout>
</LinearLayout>

及用法:

public class ProfileViewActivity extends Activity implements StartProfileListener
{
    //...
    public void startStopProfileButtonPressed (View v)
    {
        FragmentManager fm = getFragmentManager();
        StartProfileDialog profileWarningDialog = StartProfileDialog.newInstance(mProfile.name);
        profileWarningDialog.show(fm, "fragment_start_profile_dialog");
    }

    //...
    @Override
    public void onStartProfile()
    {
        //.. Do stuff here, you can supply parameters for any data you need from the spinners and use them in your activity.
    }
}

要回答您的问题,您需要在 newInstance 函数中提供 ArrayList,并在侦听器函数的微调器中传递选定的值。

【讨论】:

  • 我正在尝试将您的代码用于我的应用程序。什么是 onAttach 方法,应该如何使用?
  • onAttach 将侦听器附加到显示它的 Activity 并将其返回给对话框以供它使用,如果该 Activity 未实现接口,则抛出异常。
  • 我的类名为DialogActions,我应该如何实现这个onAttach方法?... if (activity instanceof DialogActions) { DialogActions = (DialogActions) activity; }。它不允许我像使用您的 StartProfileListener 一样使用 DialogActions
  • 我如何从活动中传递一个自定义类型 ArrayList 并从 args 中获取它?我有一个 ArrayList
  • 您应该将 DialogActions 对象作为对话框的一部分。示例:私有 DialogActions dialogListener;然后在 onAttach if (activity instanceof DialogActions) { dialogListener= (DialogActions) activity; }
【解决方案2】:

您可以使用对话框,但由于屏幕尺寸对于对话框上的大消息来说很小,所以我使用了一个活动。

您可以将其设为活动并使用 Main 活动中的 Intent 对象参数传递输入。当用户单击取消时-您可能希望返回主要活动。接受的处理可以作为此活动中按钮的单击处理程序来处理。

【讨论】:

    【解决方案3】:

    你可以使用DialogFragment,看例子here

    【讨论】:

    • 是的,我可以,但是如何传递我需要填充 Spinners 的 Arraylist?
    • 带setArguments,看例子here
    • 您可以在我的回答中看到如何将参数传入和传出对话框。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    相关资源
    最近更新 更多