วิธีตั้งค่าแอตทริบิวต์สไตล์โดยทางโปรแกรมในมุมมอง


107

ฉันได้รับมุมมองจาก XML พร้อมรหัสด้านล่าง:

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);

ฉันต้องการตั้งค่า "สไตล์" สำหรับปุ่มฉันจะทำอย่างไรใน java เนื่องจากต้องการใช้หลายสไตล์สำหรับแต่ละปุ่มที่ฉันจะใช้

คำตอบ:


52

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

นอกจากนี้ยังมีสิ่งStateListDrawableที่ช่วยให้คุณกำหนด drawables ที่แตกต่างกันสำหรับแต่ละสถานะที่คุณButtonสามารถอยู่ได้ไม่ว่าจะเน้นเลือกกดปิดใช้งานและอื่น ๆ

ตัวอย่างเช่นหากต้องการให้ปุ่มของคุณเปลี่ยนสีเมื่อกดคุณสามารถกำหนดไฟล์ XML ที่เรียกว่าres/drawable/my_button.xmlไดเร็กทอรีดังนี้:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item
    android:state_pressed="true"
    android:drawable="@drawable/btn_pressed" />
  <item
    android:state_pressed="false"
    android:drawable="@drawable/btn_normal" />
</selector>

จากนั้นคุณสามารถใช้ตัวเลือกนี้ให้โดยการตั้งค่าสถานที่ให้บริการButtonandroid:background="@drawable/my_button"


4
ปัญหาของฉันคือฉันโหลดข้อมูลจากบริการเว็บที่อธิบายข้อมูลปุ่มของฉัน ปุ่มต่างๆต้องมีรูปแบบที่แตกต่างกันตามหมวดหมู่ นั่นเป็นเหตุผลที่ฉันต้องการกำหนดสไตล์แบบไดนามิก
Lint_

3
คุณไม่สามารถเปลี่ยนstyleแอตทริบิวต์Android ได้แต่คุณสามารถตั้งค่าพื้นหลังของสิ่งที่Buttonเหมือนโดยทางโปรแกรมได้ด้วยมุมมองอื่น ๆ หากเพียงพอ นอกจากนี้ยังเป็นผู้ButtonสืบทอดจากTextViewคุณสามารถเปลี่ยนคุณสมบัติข้อความ เพียงดูเอกสาร API สำหรับรายการเหล่านี้ ... developer.android.com/reference/android/view/…
Christopher Orr

ฉันแค่คิดจะทำก่อนที่จะตรวจสอบว่าฉันมีคำตอบใหม่หรือไม่ ขอบคุณมาก.
Lint_

5
เป็นไปไม่ได้หรือที่จะสร้างสไตล์สำหรับปุ่มที่กำหนดขนาดตัวอักษรระยะขอบและอื่น ๆ จากนั้นจึงใช้สิ่งนี้กับปุ่มโดยทางโปรแกรม เป็นไปได้แน่นอนว่าถ้าฉันมีปุ่มหกปุ่มที่ต้องการมีสไตล์เดียวกัน?
แบร์

แอตทริบิวต์ใดที่เราสามารถขยายได้ เราจะขยายระยะขอบเพิ่มช่องว่างภายในได้ไหม
Android Man

49

ก่อนอื่นคุณไม่จำเป็นต้องใช้ตัวขยายโครงร่างเพื่อสร้างปุ่มง่ายๆ คุณสามารถใช้:

button = new Button(context);

หากคุณต้องการจัดรูปแบบปุ่มคุณมี 2 ทางเลือกวิธีที่ง่ายที่สุดคือเพียงระบุองค์ประกอบทั้งหมดในโค้ดเช่นเดียวกับคำตอบอื่น ๆ ที่แนะนำ:

button.setTextColor(Color.RED);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);

อีกทางเลือกหนึ่งคือกำหนดสไตล์ใน XML และนำไปใช้กับปุ่ม ในกรณีทั่วไปคุณสามารถใช้ a ContextThemeWrapperสำหรับสิ่งนี้:

ContextThemeWrapper newContext = new ContextThemeWrapper(baseContext, R.style.MyStyle);
button = new Button(newContext);

ในการเปลี่ยนแอตทริบิวต์ที่เกี่ยวข้องกับข้อความบน TextView (หรือคลาสย่อยเช่นปุ่ม) มีวิธีการพิเศษ:

button.setTextAppearance(context, R.style.MyTextStyle);

อันสุดท้ายนี้ไม่สามารถใช้เพื่อเปลี่ยนแอตทริบิวต์ทั้งหมด ตัวอย่างเช่นในการเปลี่ยนช่องว่างภายในคุณต้องใช้ไฟล์ContextThemeWrapper. แต่สำหรับสีข้อความขนาด ฯลฯ คุณสามารถsetTextAppearanceใช้ได้


1
ยอดเยี่ยมเพียง ContextThemeWrapper - คือสิ่งที่ฉันมองหามานาน
Ayaz Alifov

มันทำงานได้อย่างยอดเยี่ยม มองหาวิธีแก้ปัญหานี้มาสักพักแล้ว
jasonjwwilliams

14

ใช่คุณสามารถใช้ตัวอย่างเช่นในปุ่ม

Button b = new Button(this);
b.setBackgroundResource(R.drawable.selector_test);

5
ซึ่งจะตั้งค่าพื้นหลัง แต่สไตล์สามารถระบุได้มากกว่าแค่พื้นหลัง มุมมองจำนวนมาก (รวมถึงปุ่ม) ดูเหมือนจะมีตัวสร้างที่ใช้ ID สไตล์เป็นพารามิเตอร์ อย่างไรก็ตามฉันมีปัญหาในการทำให้มันใช้งานได้ปุ่มนี้จะแสดงเป็นข้อความโดยไม่มีขอบหรืออะไร สิ่งที่ฉันอาจทำได้คือสร้างเลย์เอาต์ที่มีเพียงปุ่มในนั้น (โดยระบุสไตล์) ขยายเลย์เอาต์นั้นจากนั้นตั้งค่าข้อความของปุ่มและอะไรก็ตาม
spaaarky21

11

คุณสามารถทำสไตล์แอตทริบิวต์ดังนี้:

Button myButton = new Button(this, null,android.R.attr.buttonBarButtonStyle);

แทนที่:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn"
    style="?android:attr/buttonBarButtonStyle"

    />

7
คำตอบที่ดีเมื่อพิจารณาจากปุ่มจะถูกสร้างขึ้น จะเป็นการดีที่จะดูวิธีการทำเช่นนั้นสำหรับปุ่มที่มีอยู่
Quality Catalyst

ดูคำตอบจาก cesards
Kristy Welsh

10

หากคุณกำลังใช้ไลบรารี Support คุณสามารถใช้ไฟล์

TextViewCompat.setTextAppearance(textView, R.style.AppTheme_TextStyle_ButtonDefault_Whatever);

สำหรับ TextViews และปุ่มต่างๆ มีคลาสที่คล้ายกันสำหรับมุมมองที่เหลือ :-)


แพ็คเกจ R ใดที่คุณต้องใช้เพื่อให้ได้รูปแบบนี้?
htafoya

6

สำหรับใครก็ตามที่กำลังมองหาคำตอบเกี่ยวกับวัสดุโปรดดูโพสต์ SO นี้: ปุ่มระบายสีใน Android พร้อมดีไซน์ Material และ AppCompat

ฉันใช้คำตอบนี้ร่วมกันเพื่อตั้งค่าสีข้อความเริ่มต้นของปุ่มเป็นสีขาวสำหรับปุ่มของฉัน: https://stackoverflow.com/a/32238489/3075340

จากนั้นคำตอบนี้https://stackoverflow.com/a/34355919/3075340เพื่อตั้งค่าสีพื้นหลังโดยทางโปรแกรม รหัสสำหรับนั้นคือ:

ViewCompat.setBackgroundTintList(your_colored_button,
 ContextCompat.getColorStateList(getContext(),R.color.your_custom_color));

your_colored_buttonอาจเป็นเพียงButtonปุ่มปกติหรือปุ่ม AppCompat ก็ได้หากคุณต้องการ - ฉันทดสอบโค้ดด้านบนด้วยปุ่มทั้งสองประเภทและใช้งานได้

แก้ไข: ฉันพบว่าอุปกรณ์ก่อนอมยิ้มไม่ทำงานกับรหัสด้านบน ดูโพสต์เกี่ยวกับวิธีเพิ่มการรองรับสำหรับอุปกรณ์ก่อนอมยิ้ม: https://stackoverflow.com/a/30277424/3075340

โดยทั่วไปทำสิ่งนี้:

Button b = (Button) findViewById(R.id.button);
ColorStateList c = ContextCompat.getColorStateList(mContext, R.color.your_custom_color;
Drawable d = b.getBackground();
if (b instanceof AppCompatButton) {
    // appcompat button replaces tint of its drawable background
    ((AppCompatButton)b).setSupportBackgroundTintList(c);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Lollipop button replaces tint of its drawable background
    // however it is not equal to d.setTintList(c)
    b.setBackgroundTintList(c);
} else {
    // this should only happen if 
    // * manually creating a Button instead of AppCompatButton
    // * LayoutInflater did not translate a Button to AppCompatButton
    d = DrawableCompat.wrap(d);
    DrawableCompat.setTintList(d, c);
    b.setBackgroundDrawable(d);
}

6

ขึ้นอยู่กับคุณลักษณะของสไตล์ที่คุณต้องการเปลี่ยนคุณอาจสามารถใช้ห้องสมุดปารีสได้:

Button view = (Button) LayoutInflater.from(this).inflate(R.layout.section_button, null);
Paris.style(view).apply(R.style.YourStyle);

รองรับแอตทริบิวต์มากมายเช่น background, padding, textSize, textColor และอื่น ๆ

Disclaimer: ฉันเขียนห้องสมุด


5

คำตอบของ @Dayerman และ @h_rules ถูกต้อง ในการยกตัวอย่างโค้ดโดยละเอียดในโฟลเดอร์ drawable ให้สร้างไฟล์ xml ที่เรียกว่า button_disabled.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" android:padding="10dp">   
 <solid android:color="@color/silver"/>
<corners
   android:bottomRightRadius="20dp"
   android:bottomLeftRadius="20dp"
   android:topLeftRadius="20dp"
   android:topRightRadius="20dp"/>
</shape>

จากนั้นใน Java

((Button) findViewById(R.id.my_button)).setEnabled(false);
((Button) findViewById(R.id.my_button)).setBackgroundResource(R.drawable.button_disabled);

การดำเนินการนี้จะตั้งค่าคุณสมบัติของปุ่มเป็นปิดใช้งานและตั้งค่าสีเป็นสีเงิน

[สีถูกกำหนดใน color.xml เป็น:

<resources>

    <color name="silver">#C0C0C0</color>

</resources>

4
@Pacerier: คำถามไม่ได้บอกอย่างนั้นเลย มีความคลุมเครือไม่ว่าสไตล์จะเป็น XML หรือใน java เพียงถามวิธีตั้งค่าสไตล์โดยใช้โปรแกรมเท่านั้น
Harvey

3

ในรันไทม์คุณจะรู้ว่าคุณต้องการให้ปุ่มของคุณมีรูปแบบใด ดังนั้นก่อนหน้านี้ใน xml ในโฟลเดอร์เลย์เอาต์คุณสามารถมีปุ่มพร้อมใช้งานพร้อมสไตล์ที่คุณต้องการได้ ดังนั้นในโฟลเดอร์เลย์เอาต์คุณอาจมีไฟล์ชื่อ: button_style_1.xml เนื้อหาของไฟล์นั้นอาจมีลักษณะดังนี้:

<?xml version="1.0" encoding="utf-8"?>
<Button
    android:id="@+id/styleOneButton"
    style="@style/FirstStyle" />

หากคุณกำลังทำงานกับชิ้นส่วนจากนั้นใน onCreateView คุณจะขยายปุ่มนั้นเช่น:

Button firstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

โดยที่ container คือคอนเทนเนอร์ ViewGroup ที่เชื่อมโยงกับเมธอด onCreateView ที่คุณแทนที่เมื่อสร้างแฟรกเมนต์ของคุณ

ต้องการปุ่มดังกล่าวอีกสองปุ่มหรือไม่? คุณสร้างสิ่งเหล่านี้:

Button secondFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);
Button thirdFirstStyleBtn = (Button) inflater.inflate(R.layout.button_style_1, container, false);

คุณสามารถปรับแต่งปุ่มเหล่านี้ได้:

secondFirstStyleBtn.setText("My Second");
thirdFirstStyleBtn.setText("My Third");

จากนั้นคุณเพิ่มปุ่มที่ปรับแต่งและมีสไตล์ของคุณลงในคอนเทนเนอร์โครงร่างที่คุณพองตัวด้วยเมธอด onCreateView:

_stylizedButtonsContainer = (LinearLayout) rootView.findViewById(R.id.stylizedButtonsContainer);

_stylizedButtonsContainer.addView(firstStyleBtn);
_stylizedButtonsContainer.addView(secondFirstStyleBtn);
_stylizedButtonsContainer.addView(thirdFirstStyleBtn);

และนั่นคือวิธีที่คุณสามารถใช้งานปุ่มที่มีสไตล์แบบไดนามิกได้


0

ฉันสร้างส่วนติดต่อผู้ช่วยสำหรับสิ่งนี้โดยใช้รูปแบบตัวยึด

public interface StyleHolder<V extends View> {
    void applyStyle(V view);
}

ตอนนี้สำหรับทุกสไตล์ที่คุณต้องการใช้ในทางปฏิบัติเพียงแค่ใช้อินเทอร์เฟซตัวอย่างเช่น:

public class ButtonStyleHolder implements StyleHolder<Button> {

    private final Drawable background;
    private final ColorStateList textColor;
    private final int textSize;

    public ButtonStyleHolder(Context context) {
        TypedArray ta = context.obtainStyledAttributes(R.style.button, R.styleable.ButtonStyleHolder);

        Resources resources = context.getResources();

        background = ta.getDrawable(ta.getIndex(R.styleable.ButtonStyleHolder_android_background));

        textColor = ta.getColorStateList(ta.getIndex(R.styleable.ButtonStyleHolder_android_textColor));

        textSize = ta.getDimensionPixelSize(
                ta.getIndex(R.styleable.ButtonStyleHolder_android_textSize),
                resources.getDimensionPixelSize(R.dimen.standard_text_size)
        );

        // Don't forget to recycle!
        ta.recycle();
    }

    @Override
    public void applyStyle(Button btn) {
        btn.setBackground(background);
        btn.setTextColor(textColor);
        btn.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
    }
}

ประกาศความเก๋ไก๋ในแบบของคุณattrs.xmlสไตล์สำหรับตัวอย่างนี้คือ:

<declare-styleable name="ButtonStyleHolder">
    <attr name="android:background" />
    <attr name="android:textSize" />
    <attr name="android:textColor" />
</declare-styleable>

นี่คือสไตล์ที่ประกาศในstyles.xml:

<style name="button">
    <item name="android:background">@drawable/button</item>
    <item name="android:textColor">@color/light_text_color</item>
    <item name="android:textSize">@dimen/standard_text_size</item>
</style>

และในที่สุดการใช้งานตัวยึดสไตล์:

Button btn = new Button(context);    
StyleHolder<Button> styleHolder = new ButtonStyleHolder(context);
styleHolder.applyStyle(btn);

ฉันพบว่าสิ่งนี้มีประโยชน์มากเนื่องจากสามารถนำมาใช้ซ้ำได้อย่างง่ายดายและรักษารหัสให้สะอาดและละเอียดฉันขอแนะนำให้ใช้สิ่งนี้เป็นตัวแปรท้องถิ่นเท่านั้นดังนั้นเราจึงสามารถอนุญาตให้ตัวเก็บขยะทำงานได้เมื่อเราตั้งค่าสไตล์ทั้งหมดเสร็จแล้ว .


-1

ฉันประสบปัญหาเดียวกันเมื่อไม่นานมานี้ นี่คือวิธีที่ฉันแก้ไข

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <!-- This is the special two colors background START , after this LinearLayout, you can add all view that have it for main background-->
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:weightSum="2"

    android:background="#FFFFFF"
    android:orientation="horizontal"
    >

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#0000FF" />

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#F000F0" />
    </LinearLayout>
    <!-- This is the special two colors background END-->

   <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:gravity="center"
    android:text="This Text is centered with a special backgound,
    You can add as much elements as you want as child of this RelativeLayout"
    android:textColor="#FFFFFF"
    android:textSize="20sp" />
</RelativeLayout>
  • ฉันใช้ LinearLayout กับ android: weightSum = "2"
  • ฉันให้องค์ประกอบลูกสองอย่าง android: layout_weight = "1" (ฉันให้ 50% ของพื้นที่หลัก (ความกว้างและความสูง))
  • และสุดท้ายฉันให้องค์ประกอบลูกสองสีพื้นหลังที่แตกต่างกันเพื่อให้ได้เอฟเฟกต์สุดท้าย

ขอบคุณ!

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