0

I want to create a Dialog from my MainActivity, with an Accept and Cancel button, that has a custom view (I have it created, a layout). In that custom dialog there're 2 spinners that I have to fill with an ArrayList that I'm giving to him (I don't know how to do that btw), and I want the user to select options from those two spinners, make them required for clicking "Accept" and when the user clicks "Accept" I have to add his creation to my database.

I'm completely lost, I only have this layout created, that is the view for the dialog, and I don't know how to do all this... Somebody please help me, this is very frustrating =(

This is the XML for the Dialog:

<?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>

This is the Class Action:

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;
  }
}

And this is the DialogActions class:

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");
        }
    }
}
  • Ok I see what you are doing wrong. You are missing the interface. Take a closer look at StartProfilerListener, this is separate from the StartProfileDialog. You'll want to do something like public interface DialogActionsListener { void doAction(int spinnerVal 1, int spinnerVal 2); } then private DialogActionsListener dialogListener; – Dave S Dec 17 '14 at 00:03
  • Yes! You were right, fixed. Now the only thing I have to know is how to make Actions parcelable, I can't understand the link you gave me :S – Nahue Federico Dec 17 '14 at 00:09
  • You'll need to make your Actions object implement Parcelable then extend ArrayList to make a custom ActionList that also implements Parcelable. Then you should be able to use the Parcelable features in your app. I haven't actually done any Parcelable coding so you'll probably want to make a new question after you've tried yourself for a while. – Dave S Dec 17 '14 at 00:11
  • Okay, so I'll make a new question. Anyways, thank you so much, you helped me a lot! :D – Nahue Federico Dec 17 '14 at 00:13

3 Answers3

3

There are many ways to do this, each with their own pro's and cons. The way I currently do it is to make each custom dialog a DialogFragment.

Here's the class

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");
        }
    }
}

And the 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>

And the usage:

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.
    }
}

To answer your question, you'd supply the ArrayList in the newInstance function, and you'd pass the selected values in the spinners in the listener function.

Dave S
  • 3,378
  • 1
  • 20
  • 34
  • I'm trying to use your code for my app. What is the onAttach method and how should I use it? – Nahue Federico Dec 16 '14 at 23:11
  • onAttach attaches the listener to the activity that shows it and returns it to the dialog for it to use, or throws an exception if that activity doesn't implement the interface. – Dave S Dec 16 '14 at 23:11
  • My class is named DialogActions, how should I implement this onAttach method?... if (activity instanceof DialogActions) { DialogActions = (DialogActions) activity; }. It doesn't let me use DialogActions as if I were using your StartProfileListener – Nahue Federico Dec 16 '14 at 23:18
  • And how do I pass a custom type ArrayList from the activity and get it from args? I have an ArrayList – Nahue Federico Dec 16 '14 at 23:25
  • You should have a DialogActions object as part of your dialog. Example: private DialogActions dialogListener; Then in onAttach if (activity instanceof DialogActions) { dialogListener= (DialogActions) activity; } – Dave S Dec 16 '14 at 23:47
  • To pass an ArrayList you probably need to use parcelable. An example of that can be seen here. http://stackoverflow.com/questions/10953121/android-arraylistmyobject-pass-as-parcelable – Dave S Dec 16 '14 at 23:48
  • I have exactly what you say: A DialogActions object and the onAttach with the same code, but it still says the same: "Incompatible conditional operand types Activity and DialogActions" and "Cannot cast from Activity to DialogActions" – Nahue Federico Dec 16 '14 at 23:51
  • Please edit your answer with the code you have and the issues you are seeing. Hard to tell why you might be getting that error without it. It could be caused by a missing import if you are using Eclipse. – Dave S Dec 16 '14 at 23:53
  • See my comment, you are trying to cast the Activity to a DialogFragment. What you want to do is define the interface like DialogActionsListener and implement that interface in your activity. Then the cast to DialogActionsListener should work. Casting to DialogActions is just wrong. – Dave S Dec 17 '14 at 00:04
  • upvote for changing names like getIdEvento to something looking normal ;) – dominik4142 Dec 17 '14 at 00:31
0

You could do with a dialog but since screen size is small for a large msg on a dialog, I used an activity.

You can make it an activity and pass input using Intent object params from Main activity. When user clicks cancel- you will probably want to go back to main activity. Handling of accept can be handled as a click handler of a button in this activity.

techtinkerer
  • 1,280
  • 2
  • 15
  • 26
0

You can use DialogFragment , look at example here.

StupidFox
  • 376
  • 3
  • 19