/**
* Notify any registered observers that the item reflected at <code>position</code>
* has been newly inserted. The item previously at <code>position</code> is now at
* position <code>position + 1</code>.
*
* <p>This is a structural change event. Representations of other existing items in the
* data set are still considered up to date and will not be rebound, though their
* positions may be altered.</p>
*
* @param position Position of the newly inserted item in the data set
*
* @see #notifyItemRangeInserted(int, int)
*/
public final void notifyItemInserted(int position) {
mObservable.notifyItemRangeInserted(position, 1);
}
翻译:通知所有已经注册的观察者,位于potision的item已经被新的item插入;之前位于position的item现在处于position+1的位置。这是一个结构性变化的事件
会有人问,那么item的子控件findViewById 去哪儿了?我们把它交给了ViewHolder的构造方法(其他方法也可以),它的本质是在onCreateViewHolder方法里生成ViewHolder的时候执行的。
举个例子:
1.ViewHolder的构造中可以通过itemView找到子控件,然后设置子控件的事件(比如点击+添加rv添加一行)
2. 但是在onbindHolder中同样对子控件进行赋值,也就是可以对子控件设置事件
3.对子控件的事件(比如添加一个data是添加一个model,然后动态添加一行,最后更新notify)这样的操作到底是写在adapter中 还是通过回调在activity中调用adapter.notifydatachangge? 因为我遇到过对datas加了一个model之后 调用notifydata 但是没有效果的时候,然而通过一个回调在activity中就没有问题了
。。。。。。。。。。。。。。。。。。。。。
notifyItemInserted调用之后
++++onCreateViewHolder
++++PayMoneyHolder
++++onBindViewHolder
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/**
* Returns the position of the ViewHolder in terms of the latest layout pass.
* <p>
* This position is mostly used by RecyclerView components to be consistent while
* RecyclerView lazily processes adapter updates.
* <p>
* For performance and animation reasons, RecyclerView batches all adapter updates until the
* next layout pass. This may cause mismatches between the Adapter position of the item and
* the position it had in the latest layout calculations.
* <p>
* LayoutManagers should always call this method while doing calculations based on item
* positions. All methods in {@link RecyclerView.LayoutManager}, {@link RecyclerView.State},
* {@link RecyclerView.Recycler} that receive a position expect it to be the layout position
* of the item.
* <p>
* If LayoutManager needs to call an external method that requires the adapter position of
* the item, it can use {@link #getAdapterPosition()} or
* {@link RecyclerView.Recycler#convertPreLayoutPositionToPostLayout(int)}.
*
* @return Returns the adapter position of the ViewHolder in the latest layout pass.
* @see #getAdapterPosition()
*/
public final int getLayoutPosition() {
return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
}
翻译:根据最新的布局返回ViewHolder的位置(position)。
使用ViewHolder的getlayoutPosition方法返回的值可能与onBindViewHolder方法传入的position可能不同。
根据SDK中的解释,在Recyclerview 进行添加、移除item等操作时,position位置可能会变化,而所有的adapter的刷新并不总是及时的,只有这个方法返回的才是当前item经过一些变换后所处的真正位置。
也就是说我们在对rv的item有数据维护操作时,应该是这样调用方法mDatas.get(getlayoutPosition()).set**(),而不是通过在onBindViewHolder中根据传入的position然后通过mDatas.get(position)获取对象并声明为全局,最后对phoneNumberItem做赋值操作,这样很有可能因为position不正确导致赋值错误。如下图:
@Override
public void onBindViewHolder(final PayMoneyHolder holder, final int position) {
this.position = position;
phoneNumberItem = mPhoneNumList.get(position);
holder.etPhoneNum.setText(phoneNumberItem.getPhoneNumber());
holder.tvPayReason.setText(phoneNumberItem.getName());
}
还有通过这个getlayoutPosition()方法,我也就比较明确了如果要添加item或者item的子控件点击等监听事件时最好是写在ViewHolder的构造中,因为可以直接调用getlayoutPosition()方法。
------------------------------------------
Process: com.mobivans.decorationcharge, PID: 23841
android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/JPEG_20180209_155151.jpg exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1958)
at android.net.Uri.checkFileUriExposed(Uri.java:2348)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:941)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9735)
at android.content.Intent.prepareToLeaveProcess(Intent.java:9720)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1795)
at android.app.Activity.startActivityForResult(Activity.java:4495)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
at android.support.v4.app.ActivityCompatJB.startActivityForResult(ActivityCompatJB.java:30)
at android.support.v4.app.ActivityCompat.startActivityForResult(ActivityCompat.java:146)
at android.support.v4.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:937)
at android.support.v4.app.FragmentActivity$HostCallbacks.onStartActivityFromFragment(FragmentActivity.java:1047)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:963)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:952)
at me.iwf.photopicker.fragment.PhotoPickerFragment$4.onClick(PhotoPickerFragment.java:173)
at me.iwf.photopicker.adapter.PhotoGridAdapter$1.onClick(PhotoGridAdapter.java:87)
at android.view.View.performClick(View.java:6303)
at android.view.View$PerformClick.run(View.java:24828)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6809)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)