简体   繁体   English

如何修复“没有附加适配器; 跳过布局“

[英]How to fix “No adapter attached; skipping layout”

I want to show ArrayList in RecycleView which wrap in the fragment, but when I run the apk, it didn't show up the RV. 我想在RecycleView中显示包含在片段中的ArrayList,但是当我运行apk时,它没有显示RV。 And when I saw on logcat, there's note "No Adapter Attached; skipping layout". 当我在logcat上看到时,会注意到“没有适配器连接;跳过布局”。

I tried so many ways to change on fragment, and adapter too, but that wasn't worked after all. 我尝试了很多方法来改变片段和适配器,但毕竟没有用。 Since the other questions on this site based on API, I don't understand, cause I'm a beginner. 由于基于API的本网站上的其他问题,我不明白,因为我是初学者。 I tried to figure out a question which based on Arraylist, the result is still the same, none of that solution is based on my problem. 我试图找出一个基于Arraylist的问题,结果仍然是相同的,没有一个解决方案是基于我的问题。

I'll show the code from my Adapter, fragment, and mainActivity, it'll long, but I want to know the problem cause I'm lost and clueless. 我将展示我的Adapter,fragment和mainActivity中的代码,它会很长,但我想知道问题导致我迷失并且无能为力。

Fragment: 分段:

public class FilmFragment extends Fragment {


    View view;
    ArrayList<Film> list = new ArrayList<>();
    RecyclerView rvCategory;
    FilmDatas filmDatas;


    public FilmFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        view = inflater.inflate(R.layout.fragment_movie,container,false);
        return view;}
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState){
        rvCategory = view.findViewById(R.id.rvCategory);
        rvCategory.setHasFixedSize(true);
        list.addAll(filmDatas.getListData());
        showRecycleList();}
private void showRecycleList(){
        rvCategory.setLayoutManager(new LinearLayoutManager(getActivity()));
        FilmAdapter adapter = new FilmAdapter(getContext());
        adapter.setListMovie(list);
        rvCategory.setAdapter(adapter);}}

Adapter: 适配器:

public class FilmAdapter extends RecyclerView.Adapter<FilmAdapter.CategotyViewHolder> {
    Context context;
    private ArrayList<Film> listFilm;


    public ArrayList<Film> getList(){ 
        return listFilm; }

    public void setListMovie(ArrayList<Film> list) {
        this.listFilm = list;}

    public FilmAdapter(Context context
    ) {this.context = context;}


    @NonNull
    @Override
    public CategotyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row_film,parent,false);
        return new CategotyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final CategotyViewHolder holder, int position) {
        final Film film = listFilm.get(position);

        Glide.with(holder.itemView.getContext()).load(film.getPhoto()).apply(new RequestOptions().override(100,100))
                .into(holder.imgPhoto);
        holder.tvName.setText(film.getName());
        holder.tvFrom.setText(film.getFrom());
        holder.tvDate.setText(film.getDate());


    }

    @Override
    public int getItemCount() {

        return getList().size();
    }

    public class CategotyViewHolder extends RecyclerView.ViewHolder {
       ImageView imgPhoto;
       TextView tvName,tvFrom,tvDate;

        public CategotyViewHolder(@NonNull View itemView) {
            super(itemView);
            imgPhoto = itemView.findViewById(R.id.img_item_photo);
            tvName = itemView.findViewById(R.id.tv_item_name);
            tvFrom = itemView.findViewById(R.id.tv_item_from);
            tvDate = itemView.findViewById(R.id.tv_date);}}

Main Activity: 主要活动:

public class MainActivity extends AppCompatActivity {
    TabLayout tabLayout;
    FrameLayout frameLayout;
    ViewPager viewPager;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        frameLayout = findViewById(R.id.Frame);
        tabLayout = findViewById(R.id.simpelTab);
        viewPager = findViewById(R.id.viewPager);
        viewPager.setAdapter(new sliderAdapter(getSupportFragmentManager()));

        tabLayout.post(new Runnable() {
            @Override
            public void run() {
                tabLayout.setupWithViewPager(viewPager);
            }
        });

        tabLayout.addOnTabSelectedListener(new TabLayout.BaseOnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }

    private class sliderAdapter extends FragmentPagerAdapter {
        String movie = "MOVIE";
        String tvShow = "TV SHOW";
        final String tabs[] = {movie, tvShow};

        public sliderAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position){
                case 0:
                    return new FilmFragment();
                case 1:
                    return new TvShowFragment();
            }
            return null;
        }

        @Override
        public int getCount() {
            return tabs.length; //count Tabs[] size: 2
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return tabs[position];
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            if (item.getItemId() == R.id.action_settings) {
                Intent mIntent = new Intent(Settings.ACTION_LOCALE_SETTINGS);
                startActivity(mIntent);
            }
        }

        return super.onOptionsItemSelected(item);
    }


    }

FilmDatas : FilmDatas:

public class FilmDatas { public static String [][] data = new String[][]{
        {
                "Venom (2018)","Investigative journalist Eddie Brock attempts a comeback following a scandal, but accidentally becomes the host of Venom, a violent, super powerful alien symbiote. Soon, he must rely on his newfound powers to protect the world from a shadowy organization looking for a symbiote of their own.","https://image.tmdb.org/t/p/w220_and_h330_face/2uNW4WbgBXL25BAbXGLnLqX71Sw.jpg","https://image.tmdb.org/t/p/w533_and_h300_bestv2/VuukZLgaCrho2Ar8Scl9HtV3yD.jpg","October 5, 2018"
        }

};
    public ArrayList<Film> getListData() {
        ArrayList<Film> list = new ArrayList<>();
        for (String[] aData : data) {
            Film film = new Film();
            film.setName(aData[0]);
            film.setFrom(aData[1]);
            film.setBackground(aData[2]);
            film.setPhoto(aData[3]);
            film.setDate(aData[4]);

            list.add(film);
        }
        return list;
    }
}

Film : (it contains parcelable and set/get) 电影:(它包含parcelable和set / get)

public class Film implements Parcelable {
    private String name,from,background,photo,date;

    public Film() {

    }


    public String getName() {return name;}
    public void setName (String name) {this.name = name;}
    public String getFrom() {return from;}
    public void setFrom (String from) {this.from = from;}
    public String getBackground() {return background;}
    public void setBackground (String background) {this.background = background;}
    public String getPhoto() {return photo;}
    public void setPhoto (String photo) {this.photo = photo;}
    public String getDate() {return date;}
    public void setDate (String date) {this.date = date;}

    protected Film(Parcel in) {
        name = in.readString();
        from = in.readString();
        background = in.readString();
        photo = in.readString();
        date = in.readString();
    }

    public static final Creator<Film> CREATOR = new Creator<Film>() {
        @Override
        public Film createFromParcel(Parcel in) {
            return new Film(in);
        }

        @Override
        public Film[] newArray(int size) {
            return new Film[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeString(from);
        parcel.writeString(background);
        parcel.writeString(photo);
        parcel.writeString(date);
    }
}

Your problem relies at your Fragment. 你的问题依赖于你的片段。

You have declared 你宣布了

FilmDatas filmDatas;

But you never instantiated it, or even fill any object of it here 但是你从来没有实例化它,甚至在这里填充它的任何对象

 @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState){
        rvCategory = view.findViewById(R.id.rvCategory);
        rvCategory.setHasFixedSize(true);
        list.addAll(filmDatas.getListData());
        showRecycleList();
}

So, there is no data to populate your list, and your recyclerview will not show anything 因此,没有数据填充您的列表,您的recyclerview将不会显示任何内容

Try by adding elements to the list like this to test 尝试通过向列表添加元素来测试

list.add(new FilmDatas("param1","param2"...))

Also, you are declaring your list as type Film, but you are populating it with FilmDatas type 此外,您将列表声明为Film类型,但您使用FilmDatas类型填充它

But I assume that filmData.getListData() returns the object of type Film that you want to populate. 但我假设filmData.getListData()返回您想要填充的Film类型的对象。

The problem is not the “No adapter attached; skipping layout” 问题不在于“No adapter attached; skipping layout” “No adapter attached; skipping layout” , the problem is that you are not adding any element to your list, and when you set the list to the adapter , it does not bind any of that data inside of each recyclerview row, and getItemCount() returns 0, and so your recyclerview does not show nothing. “No adapter attached; skipping layout” ,问题是你没有在列表中添加任何元素,当你将列表设置为适配器时,它不会绑定每个recyclerview行中的任何数据,并且getItemCount()返回0,并且所以您的recyclerview没有显示任何内容。

It would seem that your issue has to do with this code: 您的问题似乎与此代码有关:

 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState){
    rvCategory = view.findViewById(R.id.rvCategory);
    rvCategory.setHasFixedSize(true);
    list.addAll(filmDatas.getListData());
    showRecycleList();}

private void showRecycleList(){
        rvCategory.setLayoutManager(new LinearLayoutManager(getActivity()));
        FilmAdapter adapter = new FilmAdapter(getContext());
        adapter.setListMovie(list);
        rvCategory.setAdapter(adapter);}}

You are adding the list after the RecyclerView has been created without refreshing your view. 您在创建RecyclerView后添加列表而不刷新视图。 You can handle this one of two ways: update your method to update the view with the data; 您可以使用以下两种方法之一:更新您的方法以使用数据更新视图; or, pass in the data when you create the adapter. 或者,在创建适配器时传入数据。

If you wanted to just refresh the list, which is helpful for data that you might receive after the view is inflated (think of getting the data from an API request), then you just need to add notifyDataSetChanged() : 如果您只想刷新列表,这对于在视图膨胀后可能会收到的数据有用(想想从API请求中获取数据),那么您只需要添加notifyDataSetChanged()

Adapter: 适配器:

  public void setListMovie(ArrayList<Film> list) {
    this.listFilm = list;
    notifyDataSetChanged();
  }

Otherwise, you would just pass your data in when you create your adapter: 否则,您只需在创建适配器时传入数据:

Adapter: 适配器:

 public FilmAdapter(Context context, ArrayList<Film> list) {
      this.context = context;
      this.listFilm = list;
 }

Then in your Fragment you would do something like: 然后在你的Fragment你会做类似的事情:

 private void showRecycleList(){
    rvCategory.setLayoutManager(new LinearLayoutManager(getActivity()));
    if(list != null){
         FilmAdapter adapter = new FilmAdapter(getContext(), list);
         rvCategory.setAdapter(adapter);
    } else {
         //Handle error
    }

  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM