2016-10-21 21 views
11

Tôi có một tùy chỉnh LinearLayout lớp và khi tôi muốn tạo thể hiện của lớp này, tôi đã nhận ra lỗi tài sản lateinit chưa được khởi tạo Tôi đang sử dụng phiên bản mới nhất của butterknife thư việntài sản lateinit chưa được khởi tạo

đây là lớp Kotlin tôi

class MenuItemView : LinearLayout { 

@BindView(R.id.menu_title_text_view_id) 
lateinit var menuTitleTextView : CTextBasic 

constructor(ctx: Context) : super(ctx) { 
} 

init { 
    val view = LayoutInflater.from(context).inflate(R.layout.menu_item,this) 
    ButterKnife.bind(this,view) 
} 

constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) { 
    val menuAttrs = context.theme.obtainStyledAttributes(attrs, R.styleable.MenuItemView, 0, 0) 
    try { 
     val title: String = menuAttrs.getString(R.styleable.MenuItemView_menu_title) 
     menuTitleTextView.text = title 
    }catch (e : Exception){ 
     e.printStackTrace() 
    }finally { 
     menuAttrs.recycle() 
    } 
} 
fun setTitle(title : String){ 
    menuTitleTextView.text = title 
} 
} 

đây là log lỗi

kotlin.UninitializedPropertyAccessException: lateinit property menuTitleTextView has not been initialized 
at com.leavigstone.liberali.ui.custom.menu.MenuItemView.setTitle(MenuItemView.kt:48) 
at com.leavigstone.liberali.ui.activities.MainActivity.onAddButtonClick(MainActivity.java:142) 
at com.leavigstone.liberali.ui.activities.MainActivity_ViewBinding$3.doClick(MainActivity_ViewBinding.java:54) 
at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22) 
at android.view.View.performClick(View.java:4780) 
at android.view.View$PerformClick.run(View.java:19866) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5254) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 

Trả lời

1

Sử dụng Kotterknife để xem Bít-xít bơ cho Kotlin.

Sau đó, bạn có thể kết bạn với Xem

val menuTitleTextView: CTextBasic by bindView(R.id.menu_title_text_view_id) 
-2

khối khởi tạo của bạn không được gọi. Nó chỉ được gọi khi constructor chính của bạn được gọi. Trong trường hợp của bạn, hàm tạo thứ cấp được sử dụng khi xem các đối tượng được tạo từ các bố cục xml.

Thay đổi init{...} khối của bạn để fun init(){...} và gọi nó là như tuyên bố đầu tiên trong mỗi constructor

Bạn quên thêm các nhà xây dựng

constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

=> thêm nó và gọi init() trong đó

+0

khi tôi sử dụng (ctx) nó nói Biểu thức 'này' loại 'MenuItemView' không thể được gọi là hàm. Không tìm thấy hàm 'invoke()' –

+0

Tôi đã chỉnh sửa câu trả lời của mình – lukle

+0

cảm ơn, nhưng cùng một lỗi:/ –

4

Nếu bạn không muốn sử dụng bất kỳ thư viện của bên thứ ba nào, bạn có thể thêm các chức năng mở rộng này (Tôi có xu hướng có ContextExtensions.kt hoặc ViewExtensions.kt cho Context hoặc Xem hàm mở rộng có liên quan), sau đó đặt vào nó

inline fun <reified T : View> View.find(id: Int): T = findViewById(id) as T 
inline fun <reified T : View> Activity.find(id: Int): T = findViewById(id) as T 
inline fun <reified T : View> Fragment.find(id: Int): T = view?.findViewById(id) as T 

những cho phép bạn gọi find từ bên trong Activity, Fragment, và View s. Vì vậy, bên trong lớp học của bạn thay vì

@BindView(R.id.menu_title_text_view_id) lateinit var menuTitleTextView : CTextBasic 

bạn có thể có

val menuTitleTextView by lazy { find<CTextBasic>(R.id.menu_title_text_view_id) } 

Đối với những thứ như UI, nó tốt hơn để val thay vì var khi họ không cần phải thay đổi. Như một quy tắc chung trong lập trình, cố gắng giữ mọi thứ như bất biến nhất có thể, bạn sẽ nhận được ít lỗi hơn.

0

Tôi tìm thấy this phù hợp với mình.

Thay đổi build.gradle trong mô-đun dự án app của bạn.

dependencies { 
    compile "com.jakewharton:butterknife:8.8.1" 
    kapt "com.jakewharton:butterknife-compiler:8.8.1" 
} 

sử dụng kapt thay vì annotationProcessor.

và sau đó bạn có thể làm ButterKnife chú thích quen thuộc của bạn như thế này:

class MainActivity : AppCompatActivity() { 

    @BindView(R.id.myButton) 
    lateinit var myButton: Button 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     setContentView(R.layout.activity_main) 
     ButterKnife.bind(this) 
     //... 
    } 
} 

Thưởng thức.

Các vấn đề liên quan