Android notifyItemChanged()使RecyclerView滚动并跳到UP
我有一个带有适配器的RecycleView,它显示服务器列表 并且用户必须选择一台服务器 在onClick()方法中调用notifyItemChanged(previousPosition)时 要取消选择旧服务器并选择新服务器, 这使得ReCycliVIEW列表正好在列表中间跳起来。 当我点击RecycleView列表中最后2或3台服务器时,这个问题就发生了 以下是我的RecyclerView.Adapter的代码:Android notifyItemChanged()使RecyclerView滚动并跳到UP,android,android-recyclerview,Android,Android Recyclerview,我有一个带有适配器的RecycleView,它显示服务器列表 并且用户必须选择一台服务器 在onClick()方法中调用notifyItemChanged(previousPosition)时 要取消选择旧服务器并选择新服务器, 这使得ReCycliVIEW列表正好在列表中间跳起来。 当我点击RecycleView列表中最后2或3台服务器时,这个问题就发生了 以下是我的RecyclerView.Adapter的代码: public class ServerAdapter extends Recy
public class ServerAdapter extends RecyclerView.Adapter<ServerAdapter.ServerViewHolder> {
private List<Server> listServers = new ArrayList<>();
private int[] icons = new int[]{R.drawable.server1,R.drawable.server2,R.drawable.server3,R.drawable.server4,R.drawable.server5,R.drawable.server6,R.drawable.offline};
private int selected = 0;
private int previousSelected = 0;
public ServerAdapter(List<Server> listServers){
this.listServers = listServers;
}
@Override
public ServerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.server_relative_layout,parent,false);
return new ServerViewHolder(view);
}
@Override
public void onBindViewHolder(final ServerViewHolder holder, final int position) {
if(position == selected){
holder.getBackground().setSelected(true);
}else{
holder.getBackground().setSelected(false);
}
holder.getBackground().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(position != selected){
previousSelected = selected;
selected = position;
holder.getBackground().setSelected(true);
notifyItemChanged(previousSelected);
}
}
});
holder.getImageServer().setImageResource(icons[position%6]);
holder.getTextNameServer().setText(listServers.get(position).getName());
holder.getTextConnected().setText(listServers.get(position).getUrl());
}
@Override
public int getItemCount() {
return listServers.size();
}
public class ServerViewHolder extends RecyclerView.ViewHolder{
private ImageView imageServer;
private TextView textNameServer;
private TextView textConnected;
private View background;
public ServerViewHolder(View itemView) {
super(itemView);
imageServer = (ImageView)itemView.findViewById(R.id.imageServer);
textNameServer = (TextView)itemView.findViewById(R.id.textNameServer);
textConnected = (TextView)itemView.findViewById(R.id.textConnected);
background = itemView;
}
public ImageView getImageServer() {
return imageServer;
}
public TextView getTextConnected() {
return textConnected;
}
public TextView getTextNameServer() {
return textNameServer;
}
public View getBackground() {
return background;
}
}
}
公共类ServerAdapter扩展了RecyclerView.Adapter{
private List listServers=new ArrayList();
private int[]icons=new int[]{R.drawable.server1,R.drawable.server2,R.drawable.server3,R.drawable.server4,R.drawable.server5,R.drawable.server6,R.drawable.offline};
选择的私有int=0;
private int previousSelected=0;
公用服务器适配器(列表服务器){
this.listServers=listServers;
}
@凌驾
公共服务器ViewHolder onCreateViewHolder(视图组父级,int-viewType){
View=LayoutInflater.from(parent.getContext()).flate(R.layout.server\u relative\u layout,parent,false);
返回新的ServerViewHolder(视图);
}
@凌驾
BindViewHolder上的公共无效(最终服务器ViewHolder,最终int位置){
如果(位置==选定){
holder.getBackground().setSelected(true);
}否则{
holder.getBackground().setSelected(false);
}
holder.getBackground().setOnClickListener(新视图.OnClickListener()){
@凌驾
公共void onClick(视图v){
如果(位置!=选定){
previousSelected=已选择;
选择=位置;
holder.getBackground().setSelected(true);
notifyItemChanged(先前选择);
}
}
});
holder.getImageServer().setImageResource(图标[位置%6]);
holder.getTextNameServer().setText(listServers.get(position.getName());
holder.gettexconnected().setText(listServers.get(position.getUrl());
}
@凌驾
public int getItemCount(){
返回listServers.size();
}
公共类ServerViewHolder扩展了RecyclerView.ViewHolder{
私有ImageView图像服务器;
私有TextView textNameServer;
私有文本视图文本连接;
私视背景;
公共服务器视图持有者(视图项视图){
超级(项目视图);
imageServer=(ImageView)itemView.findViewById(R.id.imageServer);
textNameServer=(TextView)itemView.findViewById(R.id.textNameServer);
textConnected=(TextView)itemView.findViewById(R.id.textConnected);
背景=项目视图;
}
公共ImageView getImageServer(){
返回图像服务器;
}
公共文本视图getTextConnected(){
返回已连接的文本;
}
公共文本视图getTextNameServer(){
返回textNameServer;
}
公共视图getBackground(){
返回背景;
}
}
}
有什么解决这个问题的办法吗?谢谢
当我指定布局高度并且不让它包装内容时,问题就发生了
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="400dp"
android:id="@+id/serverRecyclerView"
android:layout_margin="10dp"
/>
或者当我把它放在下面,比如说:
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/serverRecyclerView"
android:layout_margin="10dp"
android:layout_below="@+id/image"/>
我的代码就是:
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/serverRecyclerView"
android:layout_margin="10dp"
android:layout_alignTop="@+id/imageBall"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_toRightOf="@+id/camera"
android:layout_toEndOf="@+id/camera"/>
我不知道为什么,但我使用了:
RecyclerView.setHasFixedSize(true)
这对我有用。我希望它能有所帮助。看起来这是一个bug: 最好的解决方法似乎是Bart将RecyclerView的LinearLayoutManager的AutoMeasure属性设置为false 将FixedSize设置为true解决方案有太多的副作用
setHasFixedSize(true)我遇到了类似的问题,只需处理xml布局文件即可。
不要在RecyclerView或RecyclerView的父视图中使用下面的
layout\u、上面的layout\u或其他类似属性。
您可以使用LinearLayout weight
、layout\u marginBottom
或其他方法来实现
layout\u下方
或其他。如果有人无意中发现此问题,请尝试使用
RecyclerView.ItemAnimator animator = myRecyclerListView.getItemAnimator();
if (animator instanceof SimpleItemAnimator) {
((SimpleItemAnimator)animator).setSupportsChangeAnimations(false);
}
yourRecyclerView.notifyItemChanged(int position, Object payload);
这一个帮了我的忙
使用
同样有效,但在一些边缘案例中,回收者的观点表现得很怪异。祝你好运
android:genderantfocusability=“blocksDescendants”
我的RecyclerView在ConstraintLayout中,我也遇到了这样的问题,调用RecyclerView的LayoutManager的setAutoMeasureEnabled(false)
并没有为我解决这个问题,而且这个方法在28.0.0版本中被弃用。我所做的是,我用RelativeLayout包装了我的回收视图,现在它就像一个符咒。如中所述,此“问题”是线性布局中的故意行为,不会被修复。因此,如果可能的话,只需将您的RecyclerView包装如下:
<RelativeLayout
android:id="@+id/container_messages_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/chat_back_pattern"
app:layout_constraintBottom_toTopOf="@+id/bottom_view"
app:layout_constraintTop_toBottomOf="@+id/toolbar">
<android.support.v7.widget.RecyclerView
android:id="@+id/messages_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
如果您使用NestedScrollView
作为RecyclerView
的父视图,那么延迟的答案总比没有好。您应该删除它。我遇到了类似的问题,我尝试了上面列出的所有解决方案,但没有一个有效。
我已经将“有效载荷”填充为“notifyItemChanged(position,Payloads)”,因为我只需要“上传”一个复选框值,所以我在“有效载荷”中传递该值,而不调用整个viewholder的更新。
此解决方案适用于我的recycler视图中除最后一个之外的所有视图持有者(可能适用于所有“回收”的视图持有者,我指的是那些通过“回收”现有视图来回忆“onBindViewHolder”的视图持有者)。
我认为如果您只有recyclerview,那么使用“notifyItemChanged”将有效,我还认为嵌套的滚动视图和回收器视图会引发“自动滚动”问题
我在案件中被“raed”曝光,所以“ScroolView->
setAutoMeasureEnabled(false);
<RelativeLayout
android:id="@+id/container_messages_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/chat_back_pattern"
app:layout_constraintBottom_toTopOf="@+id/bottom_view"
app:layout_constraintTop_toBottomOf="@+id/toolbar">
<android.support.v7.widget.RecyclerView
android:id="@+id/messages_list"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
msvContainer.onStopNestedScroll(mRecyclerView);
msvContainer.stopNestedScroll();