Tôi đang gặp vấn đề tương tự nhưng chưa tìm thấy cách thực tế nào để trực tiếp đặt kiểu theo chương trình, cho đến thời điểm này. Tôi muốn điền vào màn hình của tôi với rất nhiều widget, của một loại nhất định, chúng ta hãy nói nút. Không thể xác định tất cả chúng trong tệp bố cục. Tôi muốn tạo chúng theo lập trình, nhưng tôi cũng muốn xác định phong cách của chúng trong một tệp xml kiểu.
Giải pháp mà tôi đã đưa ra bao gồm xác định chỉ một trong những tiện ích đó trong tệp bố cục, tạo tất cả các tiện ích khác theo lập trình và sao chép thông tin kiểu từ người đầu tiên đến người khác.
Ví dụ sau.
Trong tệp kiểu, hãy xác định kiểu cho các nút của bạn. Ví dụ:
<style name="niceButton">
<item name="android:layout_width">160dip</item>
<item name="android:layout_height">60dip</item>
<item name="android:gravity">center</item>
<item name="android:textSize">18dip</item>
<item name="android:textColor">#000000</item>
</style>
Sau đó, lớp con "Nút", bằng cách sinh ra một lớp "NiceButton". Xác định các nhà xây dựng sẽ được cần thiết cho inflater:
public NiceButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
Sau đó xác định một nhà xây dựng, mà mục đích là để clone một nút hiện:
public NiceButton(int id, NiceButton origButton) {
super(origButton.getContext());
setId(id);
setLayoutParams(origButton.getLayoutParams());
setGravity(origButton.getGravity());
setPadding(origButton.getPaddingLeft(),
origButton.getPaddingTop(),
origButton.getPaddingRight(),
origButton.getPaddingBottom());
setTextSize(TypedValue.COMPLEX_UNIT_PX, origButton.getTextSize());
setTextColor(origButton.getTextColors());
// ... also copy whatever other attributes you care about
}
Trong file layout của bạn, xác định chỉ là một đầu các nút của bạn. Giả sử ví dụ mà bạn muốn đặt nút của bạn trong một bảng:
<TableLayout android:id="@+id/button_table"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow android:id="@+id/button_row_0">
<com.mydomain.mypackage.NiceButton
style="@style/niceButton" android:id="@+id/button_0" />
<!-- More rows/buttons created programmatically -->
</TableRow>
</TableLayout>
Chú ý rằng tên đủ tiêu chuẩn đầy đủ của lớp phụ tùng được sử dụng; rõ ràng, bạn sẽ phải thay thế com.mydomain.mypackage bằng tên gói thực tế.
Trong hoạt động của bạn, bạn có thể muốn xác định một mảng mà sẽ giữ một tham chiếu đến tất cả các nút, và một người nghe thường được gọi khi một trong các nút được nhấn:
NiceButton[] mButtonViews = new NiceButton[10];
private View.OnClickListener mNiceButtonClickListener = new View.OnClickListener() {
public void onClick(View view) {
int i = view.getId();
mButtonViews[i].setText("PRESSED!");
}
};
Lưu ý cách id chế độ xem được sử dụng làm chỉ mục trong mảng nút. Vì vậy, bạn sẽ cần các nút của bạn để có một id từ 0 đến n-1.
Cuối cùng, đây là cách bạn có thể tạo các nút của bạn trong phương thức onCreate:
// Retrieve some elements from the layout
TableLayout table = (TableLayout)findViewById(R.id.button_table);
TableRow row = (TableRow)findViewById(R.id.button_row_0);
NiceButton origButton = (NiceButton)findViewById(R.id.button_0);
// Prepare button 0
origButton.setId(0);
origButton.setText("Button 0");
origButton.setOnClickListener(mNiceButtonClickListener);
mButtonViews[0] = origButton;
// Create buttons 1 to 10
for (int i = 1; i < 10; i++) {
if (i % 2 == 0) {
row = new TableRow(this);
table.addView(row);
}
NiceButton button = new NiceButton(i, origButton);
button.setText("Button " + i);
button.setOnClickListener(mNiceButtonClickListener);
mButtonViews[i] = button;
row.addView(button);
}
Sau đây là cách màn hình xuất hiện sau khi bạn đã ép một số nút:
Vâng, có một số mã có liên quan, nhưng cuối cùng, bạn có thể tạo nhiều tiện ích bạn muốn theo chương trình và vẫn có thuộc tính được định nghĩa là kiểu.
'AttributeSet' dường như không có hàm tạo. Có thể xây dựng này mà không sử dụng xml? – Casebash
@Casebash AFAIK, bạn không thể xây dựng AttributeSet mà không sử dụng xml. Bạn có thể thiết lập tất cả các thuộc tính bằng cách sử dụng các hàm do lớp cung cấp. – Karan