【问题标题】:Change theme on runtime in Android App在 Android App 的运行时更改主题
【发布时间】:2014-02-27 02:27:36
【问题描述】:

我是 android 编程新手,我试图在我的手电筒应用上应用一个主题。错误似乎是当我尝试应用两个主题之一时单击“确定”按钮。

这是我在 SimpleNotificationAppActivity.java 上的代码

public class SimpleNotificationAppActivity extends Activity implements android.content.DialogInterface.OnClickListener{
    private boolean isFlashOn = false;
    private Camera camera;
    //private ImageButton button;
    private Button button;
    private MediaPlayer button2;

    ////////////
    public final static int CREATE_DIALOG  = -1;
    public final static int THEME_HOLO_LIGHT  = 0;
    public final static int THEME_HOLO  = 1;

    int position;
    ///////////////

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

        if (camera != null) {
            camera.release();
        }
    }




    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        //setTheme(android.R.style.Theme_Holo_Light);
        setContentView(R.layout.main);
        button = (Button) findViewById(R.id.buttonFlashlight);
        button2 = MediaPlayer.create(SimpleNotificationAppActivity.this,R.raw.two_tone_nav); //SOM DO CLIQUE
        //button = (ImageButton) findViewById(R.drawable.image_on);
        //button.setBackgroundResource(R.drawable.switch_on);
        Context context = this;
        PackageManager pm = context.getPackageManager();


        if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            Log.e("err", "Device has no camera.");
            Toast.makeText(getApplicationContext(),
                    "Sorry, your device doesn't have camera :(",
                    Toast.LENGTH_SHORT).show();

            return;
        }

        camera = Camera.open();
        final Parameters p = camera.getParameters();

        button.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                if (isFlashOn) {
                    Log.i("info", "torch is turned off!");      
                    button2.start();
                    p.setFlashMode(Parameters.FLASH_MODE_OFF);
                    camera.setParameters(p);                    
                    isFlashOn = false;
                    //button.setText("Torch-ON");
                    button.setBackgroundResource(R.drawable.button_on);
                } else {
                    Log.i("info", "torch is turned on!");
                    button2.start();
                    p.setFlashMode(Parameters.FLASH_MODE_TORCH);
                    camera.setParameters(p);                    
                    isFlashOn = true;
                    //button.setText("Torch-OFF");
                    button.setBackgroundResource(R.drawable.button_off);
                }
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_activity_actions, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item){
        super.onOptionsItemSelected(item);
        switch(item.getItemId()){
        case R.id.theme:
            themeMenuItem();
            break;
        case R.id.about:
            aboutMenuItem();
            break;
        }
        return true;

        }
    private void aboutMenuItem(){
        new AlertDialog.Builder(this)
        .setTitle("About")
        .setMessage("Flashlight app developed and designed by Rui Moreira.\n\nfacebook.com/RuiSousaMoreira")
        .setNeutralButton("Ok", new DialogInterface.OnClickListener() {


            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub

            }
        })
        .setIcon(R.drawable.app_icon_small)
        .show();
    }

    private void themeMenuItem(){

        //setTheme(android.R.style.Theme_Holo);
        //setTheme(R.layout.main2);
////////////////////////////////////////////////////
position = getIntent().getIntExtra("position", -1);

switch(position)
{
case CREATE_DIALOG:
createDialog();
break;
case THEME_HOLO_LIGHT:
setTheme(android.R.style.Theme_Holo_Light);
break;
case THEME_HOLO:
setTheme(android.R.style.Theme_Holo_Light_DarkActionBar);
break;
default:
}

//super.onCreate(savedInstanceState);
//setContentView(R.layout.main);


////////////////////////////////////////////////////


    }


    private void createDialog()
    {
        /** Options for user to select*/
        String choose[] = {"Holo Light","Holo Dark"};

        AlertDialog.Builder b = new AlertDialog.Builder(this);

        /** Setting a title for the window */
        b.setTitle("Choose your Application Theme");

        /** Setting items to the alert dialog */
        b.setSingleChoiceItems(choose, 0, null);

        /** Setting a positive button and its listener */
        b.setPositiveButton("OK", this);//
        /*TRIED THIS TOO, BUT DOESNT SOLVES THE PROBLEM
         * 
         * b.setPositiveButton("Ok", new DialogInterface.OnClickListener() {


            public void onClick(DialogInterface dialog, int which) {
            ///TESTE

                AlertDialog alert = (AlertDialog)dialog;
                int position = alert.getListView().getCheckedItemPosition();

                finish();
                Intent intent = new Intent();
                intent.putExtra("position", position);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);

                ///TESTE

            }
        });*/

        /** Setting a positive button and its listener */
        b.setNegativeButton("Cancel", null);

        /** Creating the alert dialog window using the builder class */
        AlertDialog d = b.create();

        /** show dialog*/
        d.show();
    }


    public void onClick(DialogInterface dialog, int which) {
        // TODO Auto-generated method stub
        AlertDialog alert = (AlertDialog)dialog;
        int position = alert.getListView().getCheckedItemPosition();

        finish();
        Intent intent = new Intent(this, SimpleNotificationAppActivity.class);
        intent.putExtra("position", position);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

    }

基本上当我在这里单击“主题”时:

显示此对话框:

我选择了主题,我想通过按确定来更新应用的主题。 谁能帮我实现这一目标?我感谢任何建议:)

【问题讨论】:

  • 请发布错误报告/logcat
  • 新主题需要重启才能生效,并在super.onCreate()之前应用新主题
  • Eclipse 没有显示任何错误,因为我可以运行该应用程序。当我运行它并按“确定”时,会发生这种情况 [link)(i.share.pho.to/6fc2975c_o.png)
  • @RuiMoreira 请使用imgur上传图片

标签: java android android-layout themes


【解决方案1】:

正如您所尝试的,setTheme() 是更改主题的方式。不过,

请注意,这应该在任何视图实例化之前调用 上下文(例如在调用 setContentView(View) 或 膨胀(int,ViewGroup))。

因此,您将不得不重新启动您的应用程序。我可能很脏的解决方案是杀死Activity 并使用Intent 中关于必须应用什么主题的一些信息调用您应用的主要活动。

【讨论】:

    【解决方案2】:

    正如 Little Child 所说,简单地使用 setTheme() 是行不通的。它应该在setContentView(View) 之前使用。您需要做的是在按下“确定”按钮后重新启动应用程序,然后在应用程序重新启动时通过 setTheme() 设置新主题(在 setContentView(View) 之前执行此操作)。

    要在一秒钟后重新启动应用程序,您可以使用这个(根据您的应用程序替换 Activity):

    Intent intent=new Intent (this, MainActivity.class);
    
    AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    am.set(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + 1000, 
    PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT
                            | PendingIntent.FLAG_CANCEL_CURRENT));
    finish();
    

    这是我在评论中所说的示例代码:

    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            SharedPreferences shared=getSharedPreferences("app_name", Activity.MODE_PRIVATE);
            String theme=shared.getString("theme", null);
            if(theme != null && theme.equals("LIGHT")){
                setTheme(R.style.Theme_light);
            }else{
                setTheme(R.style.Theme_dark);
            }
                setContentView(R.layout.activity_main);
    }
    

    【讨论】:

    • 感谢您的建议。我有点理解这个想法,但我不知道如何在 onCreate() 中设置主题。 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(?????????); setContentView(R.layout.main); .................
    • 我不能 setTheme(android.R.style.Theme_Holo_Light_DarkActionBar) 因为应用总是以深色主题开始,而不是选择的主题
    • 在您的情况下,您可以将主题保存在用户选择的 SharedPreferences 中,并在“OK”按钮的 onclick 方法中使用该重启代码。然后在主活动的 onCreate() 方法中,从 SharedPreferences 中获取保存的主题并将其设置为 setTheme()。我将通过添加该部分来更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多