片段中的RecyclerView:没有适配器附加跳过布局

时间:2018-05-10 12:44:46

标签: android android-fragments android-recyclerview recycler-adapter

我正在尝试在Fragment中使用RecyclerView,但我遇到了问题,我的列表没有出现,我有这个错误:

  

E / RecyclerView:没有连接适配器;跳过布局

我检查了解决方案,显然问题出现在:

  • 在Adapter

  • 之后初始化RecyclerView
  • 在onCreateView中绑定并设置recyclerView而不是onViewCreated

但是我引起了注意,我尝试了替代方案,我仍然面临同样的问题。

这是片段的代码:

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.gosia.weightapplication.databinding.FragmentHistoryBinding;
import com.example.gosia.weightapplication.model.WeightData;
import com.orhanobut.logger.Logger;
import com.raizlabs.android.dbflow.sql.language.SQLite;

import java.util.ArrayList;
import java.util.List;


public class HistoryFragment extends Fragment {

    private List<WeightData> mWeightData = new ArrayList<>();
    private FragmentHistoryBinding mFragmentHistoryBinding;
    private ListAdapter mAdapter;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_history, viewGroup, false);

        //binding variable
        mFragmentHistoryBinding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_history);
        mFragmentHistoryBinding.setVariable(this);

        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //recycler
        RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);

        // define an adapter
        mAdapter = new ListAdapter(mWeightData, getContext());
        recyclerView.setAdapter(mAdapter);

        prepareWeightData();
    }

    private void prepareWeightData() {
        mWeightData = SQLite.select().
                from(WeightData.class).queryList();

        Logger.d(mWeightData.toString()); //The list isn't null, I have data to show

        mAdapter.notifyDataSetChanged();
    }
}

XML:

    <?xml version="1.0" encoding="utf-8"?>

<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import type="android.view.View" />

        <variable
            name="variable"
            type="com.example.gosia.weightapplication.HistoryFragment" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorWhite"
        android:orientation="vertical">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:scrollbars="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <View
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/colorBlack">
            </View>

    </LinearLayout>
</layout>

ListAdapter的代码:

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;


import com.example.gosia.weightapplication.model.WeightData;

import java.util.List;

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {

    private List<WeightData> mList;
    private Context mContext;
    private final LayoutInflater mLayoutInflater;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView date, weight;
        public ImageView image;

        public ViewHolder(View v) {
            super(v);
            date = v.findViewById(R.id.text_view_date);
            weight = v.findViewById(R.id.text_view_weight);
            image = v.findViewById(R.id.image);
        }
    }

    public ListAdapter(List<WeightData> plist, Context pContext) {
        this.mList = plist;
        this.mContext = pContext;
        this.mLayoutInflater = LayoutInflater.from(this.mContext);
    }

    @Override
    public ListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = this.mLayoutInflater.inflate(R.layout.item_weight_history, parent, false);

        ViewHolder vh = new ViewHolder(v);

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        //set data
        WeightData weightData = mList.get(position);
        holder.date.setText(weightData.getLastDayWeightMeasurement());
        holder.weight.setText(weightData.getWeight());

    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
}

我的Activity正在扩展android.support.v7.app.AppCompatActivity

任何帮助将不胜感激

编辑:它显然与此DataBindingUtil有关吗?

4 个答案:

答案 0 :(得分:2)

我运行你的代码没有绑定,它的工作完美。你应该检查你的绑定

public class HistoryFragment extends Fragment {

    private ListAdapter mAdapter;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_history, viewGroup, false);
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //recycler
        RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);

        // define an adapter
        mAdapter = new ListAdapter(null, getContext());
        recyclerView.setAdapter(mAdapter);
    }

}

即使使用getContext()也可以工作,如果你传递空列表,虽然它不会在回收器视图上显示任何内容,但不会给跳过布局错误。

答案 1 :(得分:1)

将正确的上下文传递给适配器类

更改此

getContext()

getActivity()

看起来应该是这样的

mAdapter = new ListAdapter(mWeightData, getActivity(());
        recyclerView.setAdapter(mAdapter);

另外

 RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());

并始终在片段中传递使用getActivity(): - 更多信息在这里

Using context in a fragment

答案 2 :(得分:0)

如果您获取数据然后显示它,就会以这种方式进行一些更改。

    recyclerView.setLayoutManager(new LinearLayoutManager(this));
private void prepareWeightData() {
    mWeightData = SQLite.select().
            from(WeightData.class).queryList();

    Logger.d(mWeightData.toString()); //The list isn't null, I have data to show
    mAdapter = new ListAdapter(mWeightData, getContext());
    recyclerView.setAdapter(mAdapter);

    mAdapter.notifyDataSetChanged();
}

在适配器中进行一些更改..

  public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {

    private List<WeightData> mList;
    private Context mContext;

    public  class ViewHolder extends RecyclerView.ViewHolder {
        public TextView date, weight;
        public ImageView image;

        public ViewHolder(View v) {
            super(v);
            date = v.findViewById(R.id.text_view_date);
            weight = v.findViewById(R.id.text_view_weight);
            image = v.findViewById(R.id.image);
        }
    }

    public ListAdapter(List<WeightData> plist, Context pContext) {
        this.mList = plist;
        this.mContext = pContext;
    }

    @Override
    public ListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_weight_history, parent, false);

        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        //set data
        WeightData weightData = mList.get(position);
        holder.date.setText(weightData.getLastDayWeightMeasurement());
        holder.weight.setText(weightData.getWeight());

    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
}

答案 3 :(得分:0)

合并onCreateView和onViewCreated(见下文)对我有用(错误消失)

 @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_first, viewGroup, false);

        //binding variable
        mFragmentHistoryBinding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_first);
        mFragmentHistoryBinding.setVariable(this);

        //recycler
        RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);

        // define an adapter
        mAdapter = new ListAdapter(mWeightData, getContext());
        recyclerView.setAdapter(mAdapter);

        prepareWeightData();

        return view;
    }

修改

像这样更改你的适配器:

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {

    private final List<WeightData> mList;
    //... existing code

    public void updateDataSet(List<WeightData> weightData) {
        mList.clear();
        mList.addAll(weightData);
        notifyDataSetChanged();
    }

    public ListAdapter(Context pContext) {
        this.mList = new ArrayList<>();
        this.mContext = pContext;
        this.mLayoutInflater = LayoutInflater.from(this.mContext);
    }

    //... existing code

}
onCreateView中的

(从下面更新)

  // define an adapter
        mAdapter = new ListAdapter(getContext());
        recyclerView.setAdapter(mAdapter);

        prepareWeightData();

        return view;
    }

prepareWeightData方法:

private void prepareWeightData() {
    List<WeightData> weightData = SQLite.select().
            from(WeightData.class).queryList();

    Logger.d(weightData.toString()); //The list isn't null, I have data to show

    mAdapter.updateDataSet(weightData);
}