Xác định lớp con của riêng bạn về LayoutInflater.Factory có vẻ như rất nhiều công việc của tôi. Đơn giản chỉ cần ghi đè onCreateView của hoạt động() với một số mã chung:
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
View view;
// No need wasting microseconds getting the inflater every time.
// This method gets called a great many times.
// Better still define these instance variables in onCreate()
if (mInflator == null){
mInflator = LayoutInflater.from(context);
mPrefix = ((Activity) context).getComponentName().getClassName();
// Take off the package name including the last period
// and look for custom views in the same directory.
mPrefix = mPrefix.substring(0, mPrefix.lastIndexOf(".")+1);
}
// Don't bother if 'a path' is already specified.
if (name.indexOf('.') > -1) return null;
try{
view = mInflator.createView(name, mPrefix, attrs);
} catch (ClassNotFoundException e) {
view = null;
} catch (InflateException e) {
view = null;
}
// Returning null is no big deal. The super class will continue the inflation.
return view;
}
Lưu ý quan điểm tùy chỉnh phải nằm trong cùng một gói (tức là trong cùng thư mục) như hoạt động này, nhưng sau đó nó chỉ là một mảnh generic mã bạn có thể tát vào bất kỳ hoạt động nào (hoặc thậm chí tốt hơn, kế thừa từ lớp hoạt động gốc tùy chỉnh). Bạn không phải lo lắng về việc tìm ra cho một lớp học đặc biệt theo quy định tại các giải pháp được cung cấp bởi kcoppock:
if (MyCustomView.class.getSimpleName().equals(name)) {....
Bạn đang chắc chắn không tạo ra một lớp học hoàn toàn mới.
Ma thuật thực sự nằm trong lớp thư viện cốt lõi, LayoutInflator.java. Xem cuộc gọi, mPrivateFactory.onCreateView(), dưới đây ?:
if (view == null && mPrivateFactory != null) {
view = mPrivateFactory.onCreateView(parent, name, mContext, attrs);
}
if (view == null) {
if (-1 == name.indexOf('.')) {
view = onCreateView(parent, name, attrs);
} else {
view = createView(name, null, attrs);
}
}
Bạn thấy đấy, nếu cái gọi là, mPrivateFactory, trả về null (mPrivateFactory sẽ xảy ra là lớp hoạt động của bạn bằng cách này), các LayoutInflator chỉ mang về với phương pháp thay thế khác và tiếp tục lạm phát:
if (view == null) {
if (-1 == name.indexOf('.')) {
view = onCreateView(parent, name, attrs);
} else {
view = createView(name, null, attrs);
}
}
Bạn nên xem qua các lớp thư viện bằng trình gỡ lỗi IDE và thực sự xem cách hoạt động của Android.:)
Lưu ý mã, if (-1 == name.indexOf('.')) {
, dành cho bạn, những người vẫn khăng khăng đưa vào đường dẫn đầy đủ với chế độ xem tùy chỉnh của bạn, <com.wehavelongdomainname.android.ui.MyButton>
Nếu có 'dấu chấm' trong tên, thì creatview() được gọi với tiền tố (tham số thứ hai) là null: view = createView(name, null, attrs);
Tại sao tôi sử dụng phương pháp này là vì tôi đã tìm thấy có lần khi tên gói được di chuyển (tức là thay đổi) trong quá trình phát triển ban đầu. Tuy nhiên, không giống như các thay đổi tên gói được thực hiện trong chính mã java, trình biên dịch không nắm bắt những thay đổi đó và sự khác biệt hiện có trong bất kỳ tệp XML nào. Sử dụng cách tiếp cận này, bây giờ nó không phải.
Chúc mừng.
Eclipse cho tôi biết rằng không có LayoutInflater.Factory – Ragnar
@Ragnar Đã có từ API 1 (http://developer.android.com/reference/android/view/LayoutInflater.Factory.html). Bạn đã thêm nhập phù hợp cho nó chưa? – kcoppock
tìm thấy nó, tôi chỉ cần nhập android.view.LayoutInflater – Ragnar