Thay đổi chủ đề của Hoạt động theo chương trình


121

Trong những trường hợp cụ thể, tôi cần xóa chủ đề hộp thoại khỏi hoạt động của mình nhưng có vẻ như nó không hoạt động. Đây là một ví dụ

Hoạt động đầu tiên:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startActivity(new Intent(MainActivity.this, SecondActivity.class));
}

Hoạt động thứ hai:

public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setTheme(android.R.style.Theme);
    setContentView(R.layout.activity_second);
}

Trích dẫn tệp kê khai:

 <activity android:name="SecondActivity" android:theme="@android:style/Theme.Dialog"></activity>

Khi tôi chạy, hộp thoại vẫn có chủ đề.

API10

Cảm ơn.

Câu trả lời:


183

Như các tài liệu nói rằng bạn phải gọi setThemetrước bất kỳ đầu ra chế độ xem nào. Nó có vẻ như super.onCreate()tham gia vào viewquá trình xử lý.

Vì vậy, để chuyển đổi động giữa các chủ đề, bạn chỉ cần gọi setThemetrước super.onCreatenhư sau:

public void onCreate(Bundle savedInstanceState) {
    setTheme(android.R.style.Theme);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
}

Hoạt động cho tôi trên MotoG (v1) với Android 5.1. Nếu nó không hoạt động với bạn, vui lòng chia sẻ thiết bị + phiên bản Android.
lenrok258

Tôi phải xác định một chủ đề như được mô tả ở đây: stackoverflow.com/a/44236460/3211335 Và sau đó đặt nó như được mô tả trong câu trả lời này. Nó hoạt động tuyệt vời.
LaloLoop

Liệu có cách nào chúng ta có thể thiết lập chủ đề chỉ một lần ... thay vì chủ đề bộ mỗi trang
gayan1991

Tôi sử dụng tùy chọn chia sẻ để lưu chủ đề nhưng khi khởi động lại ứng dụng, trong giây lát, chủ đề đầu tiên xuất hiện sau đó chủ đề thứ hai hiển thị!
Mohammad Afrashteh

1
@ gayan1991 Bạn có thể sử dụng một hoạt động khác để xác định chủ đề của mình và làm cho tất cả các hoạt động khác của bạn mở rộng hoạt động này, ví dụ: pastebin.com/r93qrRDG Chỉnh sửa: sử dụng pastebin để có định dạng tốt hơn
SocialSupaCrew 8/1018

46

Phản hồi của user1462299 hoạt động tốt, nhưng nếu bạn bao gồm các phân đoạn , chúng sẽ sử dụng chủ đề hoạt động ban đầu. Để áp dụng chủ đề cho tất cả các phân đoạn, bạn có thể ghi đè phương thức getTheme () của Context:

@Override
public Resources.Theme getTheme() {
    Resources.Theme theme = super.getTheme();
    if(useAlternativeTheme){
        theme.applyStyle(R.style.AlternativeTheme, true);
    }
    // you could also use a switch if you have many themes that could apply
    return theme;
}

Bạn không cần gọi setTheme () trong Phương thức onCreate () nữa. Bạn đang ghi đè mọi yêu cầu để có được chủ đề hiện tại trong ngữ cảnh này theo cách này.


2
@ bất cứ ai phản đối: quan tâm giải thích những gì bạn không thích về phản hồi của tôi?
Björn Kechel

Có nên ghi đè getTheme () trong Activity hay trong các Fragment tương ứng không? Tôi đã triển khai điều này trong Activity, nhưng các Fragment vẫn đang sử dụng chủ đề Activity ban đầu.
Saltandpepper

@saltandpepper Ghi đè nó trong Hoạt động là đủ. Đảm bảo rằng mã phân đoạn và bố cục của bạn không thay đổi lại nó.
Björn Kechel

Điều này không hiệu quả với tôi, nhưng câu trả lời được cung cấp trong stackoverflow.com/a/15496425/494179 đã làm được.
Saltandpepper,

2
Điểm tốt của user1269737 nên các bạn đảm bảo không nặng tính toán. Chỉ cần trả lại một kiểu trong một trường hợp điều kiện đơn giản sẽ không ảnh hưởng đến hiệu suất.
Björn Kechel

12

Tôi biết rằng tôi đã muộn nhưng tôi muốn đăng một giải pháp ở đây:
Kiểm tra mã nguồn đầy đủ tại đây .
Đây là mã tôi đã sử dụng khi thay đổi chủ đề bằng tùy chọn ..

SharedPreferences pref = PreferenceManager
        .getDefaultSharedPreferences(this);
String themeName = pref.getString("prefSyncFrequency3", "Theme1");
if (themeName.equals("Africa")) {
    setTheme(R.style.AppTheme);



} else if (themeName.equals("Colorful Beach")) {
    //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();
    setTheme(R.style.beach);


} else if (themeName.equals("Abstract")) {
    //Toast.makeText(this, "set theme", Toast.LENGTH_SHORT).show();

    setTheme(R.style.abstract2);

} else if (themeName.equals("Default")) {

    setTheme(R.style.defaulttheme);

}

Xin lưu ý rằng bạn phải đặt mã trước setcontentview ..

GIẢI MÃ VUI VẺ!


tại sao? câu trả lời là chính xác ?!
dondondon

Tôi sử dụng tùy chọn chia sẻ để lưu chủ đề nhưng khi khởi động lại ứng dụng, trong giây lát, chủ đề đầu tiên xuất hiện sau đó chủ đề thứ hai hiển thị!
Mohammad Afrashteh

0

Cái này phù hợp với tôi:

theme.applyStyle(R.style.AppTheme, true)

Sử dụng:

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    //The call goes right after super.onCreate() and before setContentView()
    theme.applyStyle(R.style.AppTheme, true)
    setContentView(layoutId)
    onViewCreated(savedInstanceState)
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.