Android: como colocar um Enum em um pacote?

332

Como você adiciona um objeto Enum a um pacote Android?

zer0stimulus
fonte
11
Na minha opinião, os conselhos da equipe do Google são ruins. As enums são muito convenientes e sofrem a sobrecarga descrita.
Ognian
3
você pode revisitar as respostas e aceitar a segunda, se acha que pode ser uma escolha melhor.
philipp
6
Sob o título "Evitando enums" no link acima, ele agora diz o seguinte: Mitos sobre o desempenho As versões anteriores deste documento fizeram várias alegações enganosas. Abordamos alguns deles aqui.
StackOverflowed
essa seção nem está mais presente.
Nathaniel D. Waggoner

Respostas:

726

As enums são serializáveis, portanto não há problema.

Dado o seguinte enum:

enum YourEnum {
  TYPE1,
  TYPE2
}

Agrupar:

// put
bundle.putSerializable("key", YourEnum.TYPE1);

// get 
YourEnum yourenum = (YourEnum) bundle.get("key");

Intenção:

// put
intent.putExtra("key", yourEnum);

// get
yourEnum = (YourEnum) intent.getSerializableExtra("key");
miguel
fonte
Há algo de errado com este método: saving: outState.putSerializable("trollData", game.getFunkyTrolls());loading game.setFunkyTrolls((Game.FunkyTroll[]) savedInstanceState.getSerializable("trollData"));:?
Moberg
21
Eu teria votado na sua resposta, mas a pergunta era sobre como adicionar o Enum a um pacote e sua resposta explica como adicioná-lo a uma intenção ... Concedido que é quase a mesma coisa, mas Alejandro abaixo corrigiu sua resposta.
Pooks
2
ao usá-lo com o Bundle, ele lançaClassNotFoundException
Nome para exibição
2
isso pode ser super lento e não pode ser dimensionado para matrizes de coisas que contêm enum, etc. Veja stackoverflow.com/a/5551155/175156
yincrash
1
O @yincrash enum usa serialização personalizada, que é bastante rápida. Prova: docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/…
Miha_x64 19/17
164

Sei que essa é uma pergunta antiga, mas vim com o mesmo problema e gostaria de compartilhar como resolvi. A chave é o que Miguel disse: Enums são serializáveis.

Dado o seguinte enum:

enum YourEnumType {
    ENUM_KEY_1, 
    ENUM_KEY_2
}

Colocar:

Bundle args = new Bundle();
args.putSerializable("arg", YourEnumType.ENUM_KEY_1);
Alejandro Colorado
fonte
3
Com base nisso: stackoverflow.com/questions/15521309/… , as Enums personalizadas não são serializáveis. Portanto, os campos personalizados em um Enum não serão serializados. Como você lida com isso?
clu
Boa pergunta @clu! Talvez então você deve pensar em passá-lo como uma string como indicado na stackoverflow.com/questions/609860/...
Alejandro Colorado
@clu Não esperando que os campos personalizados sejam serializados. Funciona bem se for apenas um enum normal, como no código acima.
bluehallu
@AlejandroColorado, o que isso acrescenta à resposta de miguel?
tir38 17/05
1
A resposta de Miguel foi editada em 2015. A resposta original não dizia nada sobre pacotes, apenas mostrava um exemplo de intenção.
Alejandro Colorado
41

Por uma questão de integridade, este é um exemplo completo de como inserir e recuperar uma enumeração de um pacote.

Dado o seguinte enum:

enum EnumType{
    ENUM_VALUE_1,
    ENUM_VALUE_2
}

Você pode colocar a enum em um pacote:

bundle.putSerializable("enum_key", EnumType.ENUM_VALUE_1);

E recupere o enum:

EnumType enumType = (EnumType)bundle.getSerializable("enum_key");
A coisa
fonte
32

Eu uso o kotlin.

companion object {

        enum class Mode {
            MODE_REFERENCE,
            MODE_DOWNLOAD
        }
}

depois coloque em Intent:

intent.putExtra(KEY_MODE, Mode.MODE_DOWNLOAD.name)

quando você ganha para obter valor:

mode = Mode.valueOf(intent.getStringExtra(KEY_MODE))
Vladislav
fonte
6
Esta é uma resposta boa, mas pode ser complementado com um método de extensão, eu uso esta aqui: gist.github.com/Grohden/eea5ff9d5e3ba955aa2f57ff0df2683f
Gabriel De Oliveira Rohden
.nameé um caminho muito importante
Phan Van Linh
Isso parece muito mais simples do que transformar o Enum em um pacote, o que criaria mais complexidade se você trabalhar com a biblioteca de banco de dados da sala do Android .
Adam Hurwitz
@GabrielDeOliveiraRohden, não tenho certeza de que o método de extensão seja necessário, pois parece evitar apenas o uso do .namein putString(). Com o Kotlin, ele já é otimizado se estiver usando .apply. Por exemplo :ContentFragment.newInstance(Bundle().apply { putString(FEED_TYPE_KEY, SAVED.name) })
Adam Hurwitz
@AdamHurwitz, a função de extensão proposta não é o ponto inteiro das funções de extensão Kotlins? Obriga você a não cometer erros, é perfeito! @GabrielDeOliveiraRohden 's link bundle.putEnum(key, enum) | bundle.getEnum<>(key)
Yokich 15/08/19
17

Pode ser melhor passá-lo como string de myEnumValue.name () e restaurá-lo de YourEnums.valueOf (s), caso contrário, a ordem do enum deve ser preservada!

Explicação mais longa: Converter do tipo enum ordinal para enum

user602359
fonte
1
A ordem não importa se a serialização-> desserialização acontece imediatamente no tempo de execução, como ao chamar de uma atividade para outra. Pode ser um problema entre processos, como enviar Intents de um aplicativo para versões mais antigas do aplicativo.
miguel
6

Outra opção:

public enum DataType implements Parcleable {
    SIMPLE, COMPLEX;

    public static final Parcelable.Creator<DataType> CREATOR = new Creator<DataType>() {

        @Override
        public DataType[] newArray(int size) {
            return new DataType[size];
        }

        @Override
        public DataType createFromParcel(Parcel source) {
            return DataType.values()[source.readInt()];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.ordinal());
    }
}
Charlie Jones
fonte
1
Você pode usar putSerializable(key, value)/ (Type) getSerializable(key)ou putString(key, value.name())/ Type.valueOf(getString(key)), a implementação do Parcelable aqui é redundante e sem sentido.
precisa saber é o seguinte
1
Usar Parcelableé uma boa solução para armazenar matrizes de valores Enum.
RhodanV5500
2

Use bundle.putSerializable (chave String, s Serializable s) e bundle.getSerializable (chave String):

enum Mode = {
  BASIC, ADVANCED
}

Mode m = Mode.BASIC;

bundle.putSerializable("mode", m);

...

Mode m;
m = bundle.getSerializable("mode");

Documentação: http://developer.android.com/reference/android/os/Bundle.html

Peguei vocês
fonte
2

Para Intenção você pode usar desta maneira:

Intenção: kotlin

Primeira atividade:

val intent = Intent(context, SecondActivity::class.java)
intent.putExtra("type", typeEnum.A)
startActivity(intent)

Segunda atividade:

override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState) 
     //...
     val type = (intent.extras?.get("type") as? typeEnum.Type?)
}
Rasoul Miri
fonte
1

Uma coisa a ter em atenção - se você estiver usando bundle.putSerializableum a Bundlepara ser adicionado a uma notificação, poderá encontrar o seguinte problema:

*** Uncaught remote exception!  (Exceptions are not yet supported across processes.)
    java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object.

...

Para contornar isso, você pode fazer o seguinte:

public enum MyEnum {
    TYPE_0(0),
    TYPE_1(1),
    TYPE_2(2);

    private final int code;

    private MyEnum(int code) {
        this.code = navigationOptionLabelResId;
    }

    public int getCode() {
        return code;
    }

    public static MyEnum fromCode(int code) {
        switch(code) {
            case 0:
                return TYPE_0;
            case 1:
                return TYPE_1;
            case 2:
                return TYPE_2;
            default:
                throw new RuntimeException(
                    "Illegal TYPE_0: " + code);
        }
    }
}

Que pode ser usado assim:

// Put
Bundle bundle = new Bundle();
bundle.putInt("key", MyEnum.TYPE_0.getCode());

// Get 
MyEnum myEnum = MyEnum.fromCode(bundle.getInt("key"));
pequenos
fonte
0

Uma maneira simples, atribua valor inteiro a enum

Veja o seguinte exemplo:

public enum MyEnum {

    TYPE_ONE(1), TYPE_TWO(2), TYPE_THREE(3);

    private int value;

    MyEnum(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

}

Lado do Remetente:

Intent nextIntent = new Intent(CurrentActivity.this, NextActivity.class);
nextIntent.putExtra("key_type", MyEnum.TYPE_ONE.getValue());
startActivity(nextIntent);

Lado do receptor:

Bundle mExtras = getIntent().getExtras();
int mType = 0;
if (mExtras != null) {
    mType = mExtras.getInt("key_type", 0);
}

/* OR
    Intent mIntent = getIntent();
    int mType = mIntent.getIntExtra("key_type", 0);
*/

if(mType == MyEnum.TYPE_ONE.getValue())
    Toast.makeText(NextActivity.this, "TypeOne", Toast.LENGTH_SHORT).show();
else if(mType == MyEnum.TYPE_TWO.getValue())
    Toast.makeText(NextActivity.this, "TypeTwo", Toast.LENGTH_SHORT).show();
else if(mType == MyEnum.TYPE_THREE.getValue())
    Toast.makeText(NextActivity.this, "TypeThree", Toast.LENGTH_SHORT).show();
else
    Toast.makeText(NextActivity.this, "Wrong Key", Toast.LENGTH_SHORT).show();
m3esma
fonte
0

Eu acho que converter enum para int (para enum normal) e, em seguida, definir o pacote foi a maneira mais fácil. como este código para intenção:

myIntent.PutExtra("Side", (int)PageType.Fornt);

depois, para verificar o estado:

int type = Intent.GetIntExtra("Side",-1);
if(type == (int)PageType.Fornt)
{
    //To Do
}

mas não funciona para todos os tipos de enumeração!

c0mmander
fonte
0

Eu criei uma extensão Koltin:

fun Bundle.putEnum(key: String, enum: Enum<*>) {
    this.putString( key , enum.name )
}

inline fun <reified T: Enum<T>> Intent.getEnumExtra(key:String) : T {
    return enumValueOf( getStringExtra(key) )
}

Crie um pacote e adicione:

Bundle().also {
   it.putEnum( "KEY" , ENUM_CLAS.ITEM )
}

e pegue:

intent?.getEnumExtra< ENUM_CLAS >( "KEY" )?.let{}
Moises Portillo
fonte