เปลี่ยนธีมของกิจกรรมโดยทางโปรแกรม


121

ในบางกรณีฉันจำเป็นต้องลบธีมการสนทนาออกจากกิจกรรมของฉัน แต่ดูเหมือนจะใช้งานไม่ได้ นี่คือตัวอย่าง

กิจกรรมแรก:

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

กิจกรรมที่สอง:

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

ข้อความที่ตัดตอนมา:

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

เมื่อฉันเรียกใช้มันยังคงเป็นธีมโต้ตอบ

API10

ขอบคุณ

คำตอบ:


184

ตามที่เอกสารบอกว่าคุณต้องโทรsetThemeก่อนเอาต์พุตการดูใด ๆ ดูเหมือนว่าsuper.onCreate()จะมีส่วนในviewการประมวลผล

ดังนั้นในการสลับระหว่างธีมแบบไดนามิกคุณต้องโทรsetThemeมาก่อนsuper.onCreateดังนี้:

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

ใช้งานได้กับฉันบน MotoG (v1) กับ stack Android 5.1 หากไม่ได้ผลสำหรับคุณโปรดแชร์อุปกรณ์ + เวอร์ชัน Android
lenrok258

ฉันต้องกำหนดธีมตามที่อธิบายไว้ที่นี่: stackoverflow.com/a/44236460/3211335จากนั้นตั้งค่าตามที่อธิบายโดยคำตอบนี้ มันใช้งานได้ดี
LaloLoop

อย่างไรก็ตามเราสามารถตั้งธีมได้เพียงครั้งเดียว ... แทนที่จะตั้งธีมต่อหน้า
gayan1991

ฉันใช้การตั้งค่าร่วมเพื่อบันทึกธีม แต่เมื่อรีสตาร์ทแอปสักครู่ธีมแรกจะปรากฏขึ้นจากนั้นธีมที่สองจะปรากฏขึ้น!
Mohammad Afrashteh

1
@ gayan1991 คุณสามารถใช้กิจกรรมอื่นเพื่อกำหนดธีมของคุณและทำให้กิจกรรมอื่น ๆ ทั้งหมดของคุณขยายกิจกรรมนี้ได้เช่นpastebin.com/r93qrRDGแก้ไข: ใช้ pastebin เพื่อจัดรูปแบบที่ดีขึ้น
SocialSupaCrew

46

การตอบสนองของ user1462299 ใช้งานได้ดี แต่ถ้าคุณรวมส่วนย่อยไว้พวกเขาจะใช้ธีมกิจกรรมดั้งเดิม หากต้องการนำธีมไปใช้กับแฟรกเมนต์ทั้งหมดคุณสามารถแทนที่เมธอด getTheme ()ของบริบทแทน:

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

คุณไม่จำเป็นต้องเรียกใช้ setTheme () ในเมธอด onCreate () อีกต่อไป คุณกำลังลบล้างทุกคำขอเพื่อรับธีมปัจจุบันภายในบริบทนี้ด้วยวิธีนี้


2
@ ใครก็ตามที่ลงคะแนน: สนใจที่จะอธิบายว่าคุณไม่ชอบอะไรเกี่ยวกับคำตอบของฉันหรือไม่?
Björn Kechel

ควรจะลบ getTheme () ในกิจกรรมหรือใน Fragment ตามลำดับ? ฉันได้ใช้สิ่งนี้ในกิจกรรมแล้ว แต่ Fragments ยังคงใช้ธีมกิจกรรมดั้งเดิม
saltandpepper

@saltandpepper การลบล้างมันในกิจกรรมก็เพียงพอแล้ว ตรวจสอบว่าโค้ดแฟรกเมนต์และเลย์เอาต์ของคุณไม่เปลี่ยนแปลงอีก
Björn Kechel

สิ่งนี้ไม่ได้ผลสำหรับฉัน แต่คำตอบที่ให้ไว้ในstackoverflow.com/a/15496425/494179ทำได้
saltandpepper

2
user1269737 จุดดีดังนั้นคุณควรตรวจสอบให้แน่ใจว่าไม่มีการคำนวณที่หนักหน่วง การส่งคืนสไตล์ภายในกรณีเงื่อนไขง่ายๆจะไม่ส่งผลต่อประสิทธิภาพ
Björn Kechel

12

ฉันรู้ว่าฉันปลาย แต่ผมอยากจะโพสต์วิธีการแก้ปัญหาที่นี่:
ตรวจสอบรหัสที่มาเต็มได้ที่นี่
นี่คือรหัสที่ฉันใช้เมื่อเปลี่ยนธีมโดยใช้ค่ากำหนด ..

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

}

โปรดทราบว่าคุณต้องใส่รหัสก่อน setcontentview ..

HAPPY CODING!


ทำไม? คำตอบคือ corect?!
dondondon

ฉันใช้การตั้งค่าร่วมเพื่อบันทึกธีม แต่เมื่อรีสตาร์ทแอปสักครู่ธีมแรกจะปรากฏขึ้นจากนั้นธีมที่สองจะปรากฏขึ้น!
Mohammad Afrashteh

0

อันนี้ใช้ได้ดีสำหรับฉัน:

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

การใช้งาน:

  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)
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.