Элементы в RecyclerView во Fragmnet не отображаются - PullRequest
0 голосов
/ 29 июня 2018

Я видел, что есть похожие посты, но мой код совпадает с кодами в решениях, поэтому они не были полезны в моем случае. Мое приложение запускается, но отображаются две вкладки. Однако тот, который должен показывать элементы из RecyclerView, который находится в нем, пуст. Я также получаю эту ошибку:

E/RecyclerView: No adapter attached; skipping layout

Итак, у меня есть Activity с TabLayout и ViewPager

    public class MainActivity extends AppCompatActivity {
    TabLayout tabLayout;
    ViewPager viewPager;
    PagerAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tabLayout=findViewById(R.id.tab_layout);
        viewPager=findViewById(R.id.view_pager);

        tabLayout.addTab(tabLayout.newTab().setText("CitiesFragment"));
        tabLayout.addTab(tabLayout.newTab().setText("My CitiesFragment"));
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        pagerAdapter=new PagerAdapter(getSupportFragmentManager(),tabLayout.getTabCount());
        viewPager.setAdapter(pagerAdapter);

        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @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) {

            }
        });
    }
}

Это фрагмент, содержащий только RecyclerView

    public class CitiesFragment extends Fragment {
    RecyclerView recyclerView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View itemView = inflater.inflate(R.layout.cities_layout, container, false);
        recyclerView = itemView.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        List<City> data = Database.getDatabase();
        CitiesAdapter adapter = new CitiesAdapter(data);
        recyclerView.setAdapter(adapter);
        return itemView;
    }
}

Это XML для фрагмента

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

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

    </android.support.v7.widget.RecyclerView>
</LinearLayout>

А это Адаптер

    public class CitiesAdapter extends RecyclerView.Adapter<CitiesVIewHolder> {
    List<City> data;
    private int itemCount;

    public CitiesAdapter(List<City> data) {
        this.data = data;
        itemCount=data.size();
    }

    @NonNull
    @Override
    public CitiesVIewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.city_layout, viewGroup, false);
        CitiesVIewHolder viewHolder = new CitiesVIewHolder(itemView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull CitiesVIewHolder citiesVIewHolder, int position) {
        City city = data.get(position);
        citiesVIewHolder.txtCityName.setText(city.getCityName());
        citiesVIewHolder.txtCityInfo.setText(city.getCityInfo());
        LoadImageTask loadImageTask = new LoadImageTask(citiesVIewHolder.imgCity);
        loadImageTask.execute(city.getImageUrl());
    }

    @Override
    public int getItemCount() {
        return itemCount;
    }
}

И XML для адаптера

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <ImageView
            android:id="@+id/img_city"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/txt_city_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/txt_city_info"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />


</LinearLayout>

Мой PagerAdapter возвращает только один из двух фрагментов (один из них в настоящее время пуст, а другой включен в RecyclerView)

public class PagerAdapter extends FragmentStatePagerAdapter {
    private int itemCount;

    public PagerAdapter(FragmentManager fm, int itemCount) {
        super(fm);
        this.itemCount = itemCount;
    }

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

    @Override
    public int getCount() {
        return itemCount;
    }
}

Я прошу прощения за перегрузку кода, но я действительно не могу понять, что я делаю неправильно. Заранее спасибо за помощь.

Ответы [ 3 ]

0 голосов
/ 29 июня 2018

E / RecyclerView: адаптер не подключен; пропуск макета

  • TabLayout отображать фрагмент с recyclerView, но фрагменту требуется больше времени для загрузки источника данных, который создает переработчик без присоединенного адаптера.

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View itemView = inflater.inflate(R.layout.cities_layout, container, false);
        recyclerView = itemView.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        // List<City> data = Database.getDatabase(); // Don't fetch data on Main (UI) Thread 
        CitiesAdapter adapter = new CitiesAdapter(new ArrayList<City>()); // 
        recyclerView.setAdapter(adapter);
        // Display city here one background and then update adapter.
        return itemView;
    }
    
  • Если источник данных извлекает данные из локальной базы данных , тогда вы можете просто использовать handler или postDelay для RecyclerView

    recyclerView.postDelay(new Runnable(){
      public void run(){
        adapter.setCityList(result);
      }
    },500);
    
  • Если вы загружаете данные для источника данных сервера использовать фоновую задачу, вы можете проверить этот ответ для получения данных с сервера плавным способом.

// загрузка источника данных внутри асинхронной задачи.

new AsyncTaskHandler(new OnFinishCallback() {
    @Override
    public void onSuccess(List<City> result) {
        adapter.setCityList(result);
    }
}).execute("param that need to load datasource");
0 голосов
/ 30 июня 2018
  • Я создал простое приложение для имитации вашего дела.
  • RecyclerView ширина должна быть match_partent

    <!--RecyclerView width must be match_parent-->
    <android.support.v7.widget.RecyclerView
      android:id="@+id/recycler_view"
      android:layout_width="match_parent"
      android:layout_height="wrap_content">
    
  • Вы можете найти полное приложение sample / CityPreview на Github

enter image description here

0 голосов
/ 29 июня 2018

Прежде всего ваш адаптер xml root LinearLayout имеет высоту, установленную на match_parent, поэтому измените его на wrap_content.

Второй override onViewCreated и там установлено recyclerView, а не onCreateView. Например:

 @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    recyclerView = view.findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setHasFixedSize(true);
    List<City> data = Database.getDatabase();
    CitiesAdapter adapter = new CitiesAdapter(data);
    recyclerView.setAdapter(adapter);
 }

Также рассмотрите возможность добавления строки: recyclerView.setHasFixedSize(true);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...