コードBのKotlinでval backupItemList: List<MSetting>
のコンテンツを表示するRecyclerViewクラスをカスタマイズします
今、RecyclerViewクラスの外でbackupItemListのデータを変更します。コードDはUIに最新のデータを表示すると思いますが、失敗しました。UIはまだ古いデータを表示しています。最新のデータを表示するには、Code Cを使用する必要があります。
コードDの何が問題になっていますか?
コードA
class UIMain : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_main)
allList= SettingHandler().getListAllSetting()
mRecyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
mCustomAdapter= CustomAdapter(allList)
mRecyclerView.adapter= mCustomAdapter
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
//Code C
if (resultCode == RESULT_OK) {
allList=SettingHandler().getListAllSetting()
mCustomAdapter= CustomAdapter(allList)
mRecyclerView.adapter= mCustomAdapter
mCustomAdapter.notifyDataSetChanged()
mCustomAdapter.setSelectedItem(selectedBackupItem)
}
//Code D
if (resultCode == RESULT_OK) {
allList=SettingHandler().getListAllSetting()
mCustomAdapter.setSelectedItem(selectedBackupItem)
}
}
}
コードB
class CustomAdapter (val backupItemList: List<MSetting>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
val noRecord=-1
private var mSelectedItem = noRecord
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.item_recyclerview, parent, false)
return ViewHolder(v)
}
fun getSelectedItem():Int{
return mSelectedItem
}
fun setSelectedItem(index:Int){
if (index in 0..(backupItemList.size-1) ){
mSelectedItem=index
notifyDataSetChanged();
}
}
override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
holder.bindItems(backupItemList[position])
}
override fun getItemCount(): Int {
return backupItemList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(aMSetting: MSetting) {
itemView.tvSubject.text=aMSetting.name
itemView.tvCreatedDate.text=aMSetting.createdDate.toDateString()
itemView.tvDescription.text=aMSetting.description
itemView.radioButton.setOnClickListener {
mSelectedItem=adapterPosition
notifyDataSetChanged();
}
if(adapterPosition == 0 && mSelectedItem == noRecord) {
itemView.radioButton.isChecked = true
mSelectedItem=adapterPosition
}
else {
itemView.radioButton.isChecked =(adapterPosition == mSelectedItem)
}
}
}
}
civic.LiListerへ:
コードEを使用すると(コードvalをvarで置き換えます)、コードCとコードDの両方で同じ結果が得られます。なぜですか?
コードE
class CustomAdapter (var backupItemList: List<MSetting>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
val noRecord=-1
private var mSelectedItem = noRecord
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.item_recyclerview, parent, false)
return ViewHolder(v)
}
fun getSelectedItem():Int{
return mSelectedItem
}
fun setSelectedItem(index:Int){
if (index in 0..(backupItemList.size-1) ){
mSelectedItem=index
notifyDataSetChanged();
}
}
override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
holder.bindItems(backupItemList[position])
}
override fun getItemCount(): Int {
return backupItemList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindItems(aMSetting: MSetting) {
itemView.tvSubject.text=aMSetting.name
itemView.tvCreatedDate.text=aMSetting.createdDate.toDateString()
itemView.tvDescription.text=aMSetting.description
itemView.radioButton.setOnClickListener {
mSelectedItem=adapterPosition
notifyDataSetChanged();
}
if(adapterPosition == 0 && mSelectedItem == noRecord) {
itemView.radioButton.isChecked = true
mSelectedItem=adapterPosition
}
else {
itemView.radioButton.isChecked =(adapterPosition == mSelectedItem)
}
}
}
}
その秘密は多分ここに隠れるでしょう:
クラスCustomAdapter(val backupItemList:List)
CustomAdapterのインスタンスを初期化すると、値は参照が割り当てられるのではなく、プロパティbackupItemListにコピーされます。したがって、UIMainのプロパティallListを変更しても、backupItemListは期待どおりに変更されません。
Ganesh Tikoneが書いたように、ソリューションは単純です。backupItemListを更新するメソッドを追加します。
fun updateData(data: List<MovieModel>) {
backupItemList.clear()
backupItemList.addAll(data)
notifyDataSetChanged()
}
コードDを次のように変更します。
//Code D
if (resultCode == RESULT_OK) {
allList=SettingHandler().getListAllSetting()
mCustomAdapter.updateData(allList)
mCustomAdapter.setSelectedItem(selectedBackupItem)
}
やってみてください。
アクティビティのonCreateメソッド
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_main)
allList = ArrayList< MSetting>()
mCustomAdapter = CustomAdapter(mChildList)
mRecyclerView.layoutManager = LinearLayoutManager(context)
mRecyclerView.adapter = mCustomAdapter
}
> Now in onActivityResult
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
//Code C
if (resultCode == RESULT_OK) {
if(data != null){
allList.clear()
allList.addAll(SettingHandler().getListAllSetting())
mCustomAdapter.notifyDataSetChanged()
mCustomAdapter.setSelectedItem(selectedBackupItem)
}
}
}
あなたのコードDでは、あなたは参照を上書き for allListです。
また、CustomAdapterのbackupItemListには、同じものへの参照があります。したがって、allListの参照を再割り当てした場合、変更はリサイクラービューで取得されません。
最初にallListが変更可能であることを確認します
val allList = mutableListOf<MSetting>()
次にコードDで
allList.clear()
allList.addAll(SettingHandler().getListAllSetting())
mCustomAdapter.notifyDataSetChanged()
このコードをチェックして、
if (resultCode == RESULT_OK) {
allList.clear()
allList=SettingHandler().getListAllSetting()
mCustomAdapter= CustomAdapter(allList)
mRecyclerView.adapter= mCustomAdapter
mCustomAdapter.setSelectedItem(selectedBackupItem)
}
問題は、binding
を使用していないことです。つまり、list
を変更すると、Adapter
はそれを認識しないため、古いアイテムを表示するだけですが、通知するとadapter
notifyDatasetChanged
を使用したリストの変更については、新しいデータでアイテムを更新しようとします。 code D
で機能を実現したい場合は、Observableパターンを使用したデータバインディングを使用する必要があります。詳細については RecyclerViewとデータバインディング
private var adapter: RecentMovieAdapter? = null
アダプターはフラグメントのonCreateViewメソッドで初期化されます
adapter = RecentMovieAdapter(activity, this)
これはFragmentのコールバックメソッドであり、スレッド手法を使用してサーバーからデータを取得します。
override fun onDataReceived(randomDialog: List<MovieModel>) {
shimmerView!!.stopShimmerAnimation()
shimmerView!!.visibility = View.GONE
adapter!!.updateData(randomDialog)
}
private var movieList: MutableList<MovieModel> = mutableListOf<MovieModel>()
このようにアダプタクラスに更新機能を追加
fun updateData(data: List<MovieModel>) {
movieList.clear()
movieList.addAll(data)
notifyDataSetChanged()
}
yourAdapter()。notifyDataSetChanged