Đặt kiểu cho TextView theo lập trình


249

Tôi đang cố gắng sử dụng hàm TextViewtạo với kiểu như thế này:

TextView myText = new TextView(MyActivity.this, null, R.style.my_style);

Tuy nhiên, khi tôi thực hiện việc này, chế độ xem văn bản không xuất hiện theo kiểu (tôi đã xác minh kiểu bằng cách đặt nó trên một đối tượng tĩnh).

Tôi cũng đã thử sử dụng myText.setTextAppearance(MyActivity.this, R.style.my_style)nhưng nó cũng không hoạt động.

Câu trả lời:


318

Tôi không tin bạn có thể thiết lập phong cách theo chương trình. Để giải quyết vấn đề này, bạn có thể tạo tệp xml bố cục mẫu với kiểu được gán, ví dụ như trong res / layout tạo tvtemplate.xml như với nội dung sau:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="This is a template"
        style="@style/my_style" />

sau đó thổi phồng điều này để khởi tạo TextView mới của bạn:

TextView myText = (TextView)getLayoutInflater().inflate(R.layout.tvtemplate, null);

Hi vọng điêu nay co ich.


1
Trường hợp điều này chiến thắng câu trả lời của Dandre Allison là nó không yêu cầu API v11.
Martin Capodici

2
Nó có thể đã làm việc, nhưng điều này không có ý nghĩa. Làm thế nào nó có thể được thiết lập với tập tin xml? nếu không lập trình . Có nhiều lý do để không sử dụng các tệp xml, một trong số đó là tôi được sử dụng để viết mã để xây dựng giao diện người dùng vì vậy tôi không muốn tìm hiểu một cách làm mới vì bộ nhớ của tôi bị hạn chế và tôi muốn giữ một số chỗ cho những thứ khác.
Iharob Al Asimi

@IharobAlAsimi đúng vậy, tất cả mọi thứ đều có thể được thực hiện theo chương trình và LayoutInflater biết mọi thứ về việc biến XML thành các đối tượng. Đáng buồn thay, nhiều thứ như vậy bị ẩn dưới các API riêng tư và cách duy nhất để tạo một số đối tượng là cung cấp Attributionset cho nhà xây dựng.
Miha_x64

Không giống như tất cả các câu trả lời khác, điều này thực sự có hiệu quả với người quay, vì vậy, một ngôi sao vàng dành cho bạn
Rowan Berry

121

Bạn có thể tạo một kiểu chung và sử dụng lại nó trên nhiều khung nhìn như kiểu dưới đây:

textView.setTextAppearance(this, R.style.MyTextStyle);

Chỉnh sửa: điều này đề cập đến bối cảnh


50
Câu trả lời của bạn hoạt động miễn là tất cả những gì bạn làm là đánh lừa "phong cách" của văn bản. Nó không hoạt động nếu bạn đang cố gắng làm những thứ khác cho TextView như thêm phần đệm hoặc lề. Vì vậy, tôi không nói bạn sai, nhưng câu trả lời của bạn bị hạn chế. Thổi phồng khung nhìn khi chạy là cách duy nhất để áp dụng một phong cách toàn diện.
Bill Mote

1
Cả hai giải pháp sử dụng một mẫu bị thổi phồng và sử dụng setTextAppparent đều hợp lý. Để giải quyết vấn đề đệm / lề cho giải pháp thứ 2, bạn có thể gọi textView.setLayoutParams (layoutParams)
AlanKley

Phương pháp này không được dùng ở cấp API 23. Thay vào đó, hãy sử dụng setTextAppparent (int) trong API 23+.
Sergii

Đảm bảo phiên bản ít nhất là API 23 (M)
Br0thazS0ul

4
sử dụng phương pháp từ thư viện hỗ trợ,TextViewCompat.setTextAppearance
Rubin Yoo

97

Bạn có thể chuyển ContextThemeWrapper cho hàm tạo như thế này:

TextView myText = new TextView(new ContextThemeWrapper(MyActivity.this, R.style.my_style));

1
công cụ tuyệt vời! cách duy nhất tôi có thể thiết lập các kiểu lập trình trong khi hỗ trợ API 8.
tbraun 23/11/13

Vì một số lý do, nó không ảnh hưởng đến phong cách của nút của tôi. Tôi đã xác định phong cách của tôi như : <style name="TabButton"><item name="android:background">@drawable/tabbar_button_bkgnd</item>...</style>. Và sau đó tôi gọi nó với một công trình : new Button(new ContextThemeWrapper(context, R.style.TabButton));. Nhưng nút chỉ đơn giản là bỏ qua các thiết lập của tôi. Tôi có làm gì sai ở đây không?
Aleks N.

@ AlaksiejN. Bạn nên kế thừa từ Widget.Button style như thế nàyparent="@android:style/Widget.Button"
maxcanna

@maxcanna Vì một số lý do, việc thêm parentkhông thay đổi một chút. Vì vậy, tôi chỉ đi trước với inflategiải pháp.
Aleks N.

11
@AliakseiN. Bạn cần sử dụng hàm tạo 3-arg, vd new Button(new ContextThemeWrapper(context, R.style.TabButton), null, 0). Mặt khác, kiểu nút mặc định sẽ được áp dụng và kiểu này sẽ ghi đè kiểu nút mà bạn đã hợp nhất vào chủ đề thông qua ContextThemeWrapper.
Newtonx

17

Bạn có thể đặt kiểu trong hàm tạo (nhưng không thể thay đổi / đặt kiểu động).

View(Context, AttributeSet, int)( intthuộc tính trong chủ đề hiện tại có chứa tham chiếu đến kiểu)

Trả lời từ Romain Guy

tài liệu tham khảo


câu trả lời của bạn là sai lệch - bạn đã thử đọc chủ đề này đến cùng chưa?
andr

3
Làm thế nào là nó đánh lừa? Câu trả lời được chấp nhận là sai lệch, bởi vì Romain Guy nói rõ ràng rằng bạn có thể "thiết lập" một phong cách lập trình. Không có cơ sở để thay đổi nó một cách linh hoạt. Chủ đề này dường như không nghĩ rằng đó là trường hợp mặc dù.
Dandre Allison

1
Coi chừng, cuộc gọi này yêu cầu API cấp 11.
Martin Capodici

1
@PaulVerest nó không phải là một trích dẫn.
Dandre Allison

6
Int cuối cùng không phải là một tài nguyên phong cách. Đó là "Một thuộc tính trong chủ đề hiện tại có chứa tham chiếu đến tài nguyên kiểu cung cấp các giá trị mặc định cho chế độ xem."
RVE

11

Tham số int defStyleAttrkhông chỉ định kiểu. Từ tài liệu Android:

defStyleAttr - Một thuộc tính trong chủ đề hiện tại có chứa tham chiếu đến tài nguyên kiểu cung cấp các giá trị mặc định cho chế độ xem. Có thể là 0 để không tìm kiếm mặc định.

Để thiết lập kiểu trong View constructor, chúng ta có 2 giải pháp khả thi:

  1. Với việc sử dụng ContextThemeWrapper:

    ContextThemeWrapper wrappedContext = new ContextThemeWrapper(yourContext, R.style.your_style);
    TextView textView = new TextView(wrappedContext, null, 0);
  2. Với hàm tạo bốn đối số (có sẵn bắt đầu từ LOLLIPOP):

    TextView textView = new TextView(yourContext, null, 0, R.style.your_style);

Điều quan trọng cho cả hai giải pháp - defStyleAttrtham số nên là 0 để áp dụng kiểu của chúng ta vào khung nhìn.


5

Thay đổi kiểu động không được hỗ trợ (chưa). Bạn phải đặt kiểu trước khi chế độ xem được tạo, thông qua XML.


20
thực tế cũng xảy ra như vậy
njzk2

@ njzk2 cảm ơn ... rõ ràng là không nghĩ về bình luận của anh ấy trước khi đăng. Không có cách nào để thiết lập kiểu theo lập trình trước khi UI được xây dựng, do đó, cùng một mã sẽ được sử dụng để thay đổi hoặc đặt kiểu theo lập trình.
Chris Cashwell

3

Câu trả lời được chấp nhận là giải pháp tuyệt vời cho tôi. Điều duy nhất để thêm là về inflate()phương pháp.

Trong câu trả lời được chấp nhận, tất cả các android:layout_*tham số sẽ không được áp dụng.

Lý do là không có cách nào để điều chỉnh nó, nguyên nhân nullđã được thông qua như ViewGroup parent.

Bạn có thể sử dụng nó như thế này:

View view = inflater.inflate(R.layout.view, parent, false);

parentViewGroup, từ nơi bạn muốn điều chỉnh android:layout_*.

Trong trường hợp này, tất cả các thuộc tính tương đối sẽ được thiết lập.

Hy vọng nó sẽ hữu ích cho ai đó.


2

Khi sử dụng chế độ xem tùy chỉnh có thể sử dụng kế thừa kiểu (hoặc thuộc tính có thể tạo kiểu sự kiện), bạn phải sửa đổi hàm tạo thứ hai để không bị mất kiểu. Điều này làm việc cho tôi, mà không cần sử dụng setTextAppearence () :

public CustomView(Context context, AttributeSet attrs) {
    this(context, attrs, attrs.getStyleAttribute());
}

2

Tôi cũng gặp vấn đề và tôi đã tìm ra cách thiết lập phong cách theo chương trình. Có lẽ tất cả các bạn cần nó, vì vậy tôi cập nhật ở đó.

Tham số thứ ba của hàm tạo View chấp nhận một loại attr trong chủ đề của bạn dưới dạng mã nguồn bên dưới:

public TextView(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.textViewStyle);
}

Vì vậy, bạn phải vượt qua một loại R.attr. ** chứ không phải R.style. **

Trong mã của tôi, tôi đã làm theo các bước sau:

Đầu tiên, tùy chỉnh một attr tùy chỉnh sẽ được sử dụng bởi các chủ đề trong attr.xml.

<attr name="radio_button_style" format="reference" />

Thứ hai, cụ thể phong cách của bạn trong chủ đề được sử dụng của bạn trong style.xml.

 <style name="AppTheme" parent="android:Theme.Translucent">
    <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    <item name="radio_button_style">@style/radioButtonStyle</item>
</style>
<style name="radioButtonStyle" parent="@android:style/Widget.CompoundButton.RadioButton">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">64dp</item>
    <item name="android:background">#000</item>
    <item name="android:button">@null</item>
    <item name="android:gravity">center</item>
    <item name="android:saveEnabled">false</item>
    <item name="android:textColor">@drawable/option_text_color</item>
    <item name="android:textSize">9sp</item>
</style>

Cuối cùng, sử dụng nó!

            RadioButton radioButton = new RadioButton(mContext, null, R.attr.radio_button_style);

Chế độ xem được tạo theo chương trình sẽ sử dụng kiểu được chỉ định trong chủ đề của bạn.

Bạn có thể dùng thử, và hy vọng nó có thể làm việc cho bạn một cách hoàn hảo.


0

Tôi chỉ thử nghiệm với EditText nhưng bạn có thể sử dụng phương thức

công khai void setBackgroundResource (int Resid)

để áp dụng một kiểu được định nghĩa trong tệp XML.

Sine phương thức này thuộc về View Tôi tin rằng nó sẽ hoạt động với bất kỳ thành phần UI nào.

Trân trọng.


Theo tài liệu này chỉ nên làm việc với drawable, không phải với phong cách. Do đó, nếu điều này thực sự hoạt động, nó chỉ "tình cờ" và bạn không nên dựa vào nó.
Heinzi

0

Chúng ta có thể sử dụng TextViewCompact.setTextAppearance(textView, R.style.xyz).

Tài liệu Android để tham khảo.

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.