Kotlin Android Extensions는 활동/조각/어댑터에서 직접 ID를 사용하는 방법을 제공합니다. 그래서 내가 원하는 것은 어댑터에 대한 일반적인 방법이며 어댑터 자체가 아닌 어댑터 사용자에게 바인드 뷰 책임을 남겨 둡니다. 예를 들어 : 나는 모든 단일 레이아웃과 파일 어댑터에 대한 동일한 코드를 다시 작성하지 않고도 원하는대로 그냥 어댑터를 결합하는 레이아웃 파일 및 바인드 기능을 전달할 수Kotlin Android Extension을 사용하여 어댑터에서 뷰 바인딩을 연기 할 수 있습니까?
class GenericAdapter<T>(
@LayoutRes private val layoutId: Int,
private var list: List<T>,
inline private val bind: (View, T, Int) -> Unit) : RecyclerView.Adapter<InnerHolder>() {
override fun onBindViewHolder(holder: InnerHolder?, position: Int) {
holder?.containerView?.let {
bind(holder.containerView, list[position], position)
}
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): InnerHolder =
InnerHolder(LayoutInflater.from(parent?.context).inflate(layoutId,
parent,
false))
override fun getItemCount(): Int = list.size
class InnerHolder(
val containerView: View?) : RecyclerView.ViewHolder(containerView)
}
.
여기에 문제가 있습니다. ViewHolder 패턴은 ChildView가 부풀려 질 때마다 "findViewById"호출을 제거하려고합니다. 하지만 내 어댑터의 구현. 어댑터가 뷰를 바인드 할 때마다 "findViewById"를 호출해야합니다.
편집 : "캐시"문제에 대한 세부 정보입니다.
활동 내에서 GenericAdapter
사용
override fun onCreated(savedInstanceState: Bundle?){
list.adapter = GenericAdapter<Item>(items){ view,item,position ->
view.textview.text = item.text
}
}
처럼이이에 디 컴파일됩니다
TextView var2 = (TextView)var10000.findViewById(id.textview);
Intrinsics.checkExpressionValueIsNotNull(var2, "itemView.tv_text");
var2.setText((CharSequence)String.valueOf(var1));
그러나 그들은 예를 들어 LayoutContainer
안드로이드 확장과 실험 도구가 있습니다
class InnerHolder(
override val containerView: View?) : RecyclerView.ViewHolder(containerView), LayoutContainer {
fun bind(int: Int) {
textview.text = int.toString()
}
}
을 그리고 이것은 완벽하게 캐시를 사용합니다 조회수 :
TextView var10000 = (TextView)this._$_findCachedViewById(id.tv_text);
그러나 문제는 캐시 된 뷰가 LayoutContainer의 범위 안에 있어야한다는 것입니다. 예를 들어이 구현 작동 실 거예요 :
TextView var10000 = (TextView)$receiver.getContainerView().findViewById(id.tv_text);
그래서 제 질문은 어떤 방법으로 캐시를 유지하는 방법이 아직 안드로이드를 사용 :
class InnerHolder(
override val containerView: View?) : RecyclerView.ViewHolder(containerView), LayoutContainer {
fun bind(int: Int) {
this.bindInt(int)
}
}
// some extension function outside the ViewHolder Scope.
fun LayoutContainer.bindInt(int: Int) {
tv_text.text = int.toString()
}
이 여전히보기를 찾기 위해 findViewById를 사용합니다 확장 기능은 어댑터가 있지만 뷰 소유자의 범위 밖에 있습니까?
홀더 클래스 안에 모든'View' 참조를 넣고'init' 블록에서만'findViewById'를 호출 할 수 있습니다. – Ircover
주어진 모호성을 반영하여 질문을 업데이트하십시오. 또한 어댑터를 인스턴스화하는 유스 케이스를 추가하십시오. 어쩌면 내가 나중에 대답을 찾을거야 ... – tynn
@ tynn 예. 업데이트를 확인하십시오. 시간 내 줘서 고마워! –