Показывать случайные XML-файлы в Android

#android #layout #random

#Android #макет #Случайный

Вопрос:

В моем приложении для Android я нажимаю на кнопку «Случайный», и приложение показывает мне случайный XML-файл из first.xml , second.xml или third.xml . Это работает нормально, но я подумал, есть ли более простой или приятный способ реализовать это, если у вас более 100 XML-файлов.

Я нашел некоторый код (который отлично работает), который показывает случайные просмотры изображений:

     private Integer [] mImageIds = { 
        R.drawable.one, 
        R.drawable.two, 
        R.drawable.three, 
        };
   private static final Random rgenerator = new Random();

   private ImageView iv;

   .
   .
   .

   Integer q = mImageIds[rgenerator.nextInt(mImageIds.length)];

   iv = (ImageView) findViewById(R.id.imageviewyeah);
   iv.setImageResource(q);
  

Вот как мой main.xml выглядит:

     <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
<Button
        android:id="@ id/first_button"
        android:onClick="change"
        android:text="first"
        android:layout_width="fill_parent"
    android:layout_height="wrap_content"
        />
<Button
        android:id="@ id/second_button"
        android:onClick="change"
        android:text="second"
        android:layout_width="fill_parent"
    android:layout_height="wrap_content"
        />
<Button
        android:id="@ id/third_button"
        android:onClick="change"
        android:text="third"
        android:layout_width="fill_parent"
    android:layout_height="wrap_content"
        />
<Button
        android:id="@ id/random_button"
        android:onClick="change"
        android:text="random"
        android:layout_width="fill_parent"
    android:layout_height="wrap_content"
        />
  

и это код, который обрабатывается при нажатии на кнопку:

     package com.random;

    import java.util.Random;

    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;

    public class Main extends Activity {
      @Override
      public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
}

public void change(final View view){
    switch (view.getId()) {
    case R.id.first_button:
        startActivity(new Intent(this, FirstPage.class));
        break;
    case R.id.second_button:
        startActivity(new Intent(this, SecondPage.class));
        break;
    case R.id.third_button:
        startActivity(new Intent(this, ThirdPage.class));
        break;
    case R.id.random_button:

        Random random = new java.util.Random();
        int rand = random.nextInt(3);

        switch (rand) {
        case 0:
            startActivity(new Intent(this, FirstPage.class));
            break;
        case 1:
            startActivity(new Intent(this, SecondPage.class));
            break;
        case 2:
            startActivity(new Intent(this, ThirdPage.class));
            break;
            }
        }
    }
}
  

Любая помощь очень ценится!


Теперь у меня возник довольно похожий вопрос. До сих пор я реализовал «случайную» кнопку. Если вы нажмете на него, будет показан случайный xml-файл. Примечание: Содержимое (просмотр текста, просмотр изображений) отличается в xml-файлах, но код Java (нажатие на кнопки и т.д.) Тот же!

Это код, если вы нажмете на «Случайную» кнопку:

     switch (view.getId()) {
    case R.id.first_button:
        startActivity(new Intent(this, FirstPage.class));
        break;
    case R.id.second_button:
        startActivity(new Intent(this, SecondPage.class));
        break;
    case R.id.third_button:
        startActivity(new Intent(this, ThirdPage.class));
        break;
    case R.id.random_button:
        Intent intent = new Intent(this, DisplayRandomPage.class);
        startActivity(intent);
  

и это находится в DisplayRandomPage.class

     public class DisplayRandomPage extends Activity {

private Integer [] mLinearLayoutIds = { 
        R.layout.one
        R.layout.two,
        R.layout.three
        };

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 


    Random random = new java.util.Random();
    int rand = random.nextInt(3);

    setContentView(mLinearLayoutIds[rand]);
            }
    }
  

Что я хотел бы сделать, так это создать DisplaySpecificPage.class . Выше я показал свой main.class с предложением switch-case. Итак, когда я нажимаю на первую кнопку, запускается FirstPage.class нажав на второй, он запустится SecondPage.class и так далее. Итак, для каждого xml-файла я должен создать новый java-класс, хотя разные java-классы делают все то же самое. Отличаются только XML-файлы. Итак, я хотел бы поместить что-то вроде этого:

псевдокод:

     case R.id.first_button:
    startActivity(new Intent(this, DisplaySpecificPage.class)) with R.layout.first_page;
    break;
  

как мне передать идентификатор из макета (R.layout.first_page) дальше?

Ответ №1:

Если все ваши классы выполняют одно и то же, за исключением того, что вызывается другой макет, вы могли бы создать единый класс отображения

 public class DisplayPage extends Activity 
  

и отправьте ему идентификатор макета в дополнительных настройках intent.

Вы можете получить идентификатор, выполнив что-то вроде

 Class c = Class.forName("com.random.R$layout");
Integer iLayout = new Integer(c.getField("layout" rand).getInt(new R.layout()));
  

(предполагая, что ваши макеты вызываются layout1.xml , layout2.xml и т.д.)

Отправьте его на свою страницу отображения,

 Intent intent = new Intent(this, DisplayPage.class);
intent.putExtra("Layout", iLayout);
startActivity(intent);
  

и верните его, выполнив что-то вроде

 public void onCreate(Bundle savedInstanceState)
{
  super.onCreate(savedInstanceState);

  // default value
  int iLayout = R.id.main;

  if (savedInstanceState != null)
  {
    iLayout = savedInstanceState.getInt("Layout");
  }
  else
  {
    Bundle extras = getIntent().getExtras();
    if (extras != null)
    {
      iLayout = extras.getInt("Layout");
    }
  }

  setContentView(iLayout);

}
  

Вы также захотите переопределить onSaveInstanceState для включения этого int, чтобы, например, изменение ориентации экрана не заставляло его забывать, что он показывал.


 try
{
  Class c = Class.forName("com.random.R$layout");
  Field[] aFields = c.getFields();

  Random random = new Random();      
  boolean isUsableLayout = false;
  Integer iLayout = 0;

  while (!isUsableLayout)
  {
    int rand = random.nextInt(aFields.length);      
    iLayout = new Integer(c.getField(aFields[rand].getName()).getInt(new R.layout()));

    if (iLayout != R.layout.main)
    {
      isUsableLayout = true;
    }
  }

  Intent intent = new Intent(this, DisplayPage.class);
  intent.putExtra("Layout", iLayout);
  startActivity(intent);
}
catch (Exception e)
{
  e.printStackTrace();
}
  

Комментарии:

1. Привет, Бен! Я сделал то, что вы опубликовали, и это работает! Но я переименовал эти три образца макетов в layout1, layout2, … На самом деле у моих макетов нет таких похожих названий. Я думал о том, чтобы сделать что-то вроде этого: private Integer [] mLinearLayoutIds = { R.id.один, R.id.два, R.id.три, }; у вас есть представление о том, как это будет работать?

2. Вы могли бы использовать Field[] afFields = c.getFields() для возврата всех идентификаторов макета в виде массива полей, выбрать один из них случайным образом, проверить, что это не тот макет, который вы не хотите использовать (например, main), и использовать это. В противном случае вам пришлось бы вручную записывать все более ста идентификаторов макета в свой массив.

3. Еще раз привет! Кажется, я застрял здесь. никогда раньше не использовал поля. Итак, это фрагмент кода в моем предложении switch-case «now»: Class<?> c = Class.forName("com.random.R$layout"); java.lang.reflect.Field[] afFields = c.getFields(); Теперь я не знаю, как передать его в DisplayPage.class и не знаю, как это использовать там тогда. Наконец, я хотел бы знать, нужно ли мне проверять наличие макетов, которые я не хочу показывать (например, main), если я не указываю макетам идентификатор, или я полностью ошибаюсь. Если да, то как мне проверить наличие нежелательных макетов? вот так: (if afFields == main) then randomize again Спасибо!!!

4. Отредактированный оригинальный комментарий с примером. Всем созданным макетам присваивается идентификатор и они автоматически добавляются в R.layout во время сборки.

5. Готово! Это отлично работает! Большое спасибо за это! Теперь только один последний вопрос на будущее, если мне это может понадобиться однажды. Что мне пришлось бы написать, если бы я использовал такой целочисленный массив private Integer [] mLinearLayoutIds = { R.id.one, R.id.two, R.id.three, } ? Еще раз спасибо!