在recyclerview中将高度设置为wrap_content时,不显示图像

时间:2018-03-17 08:25:02

标签: android android-recyclerview

我想做什么?

垂直显示20张图像。滚动到最后一个图像(分页或无限滚动)时,必须请求接下来的20个图像。

发生了什么事?

使用设置了高度的recyclerview到wrap_content:没有显示任何图像。

使用recylerview将height设置为match_parent:我可以看到图像,但是在显示第5张图像时会调用以下请求。但我希望在滚动到最后一张图像时调用它。

标题

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="technology.nine.moviedb.MainActivity">

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

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

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:id="@+id/progress"
        android:visibility="visible"/>

</RelativeLayout>

item_movie.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/item_movie">

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

</LinearLayout>

Main_activity.java

package technology.nine.moviedb;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ProgressBar;
import android.widget.Toast;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import technology.nine.moviedb.adapter.MovieAdapter;
import technology.nine.moviedb.api.ApiClient;
import technology.nine.moviedb.api.ApiInterface;
import technology.nine.moviedb.model.Movie;
import technology.nine.moviedb.model.MovieResponse;

public class MainActivity extends AppCompatActivity {

    public static final String API_KEY = "9c7b8cc9de4995efcf3705b49f54dca8";
    Boolean isScrolling = false;
    int currentPage = 1;
    int currentItems, totalItems, scrollOutItems;
    RecyclerView recyclerView;
    LinearLayoutManager linearLayoutManager;
    MovieAdapter movieAdapter;
    ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar = (ProgressBar) findViewById(R.id.progress);
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        linearLayoutManager = new LinearLayoutManager(this);
        movieAdapter = new MovieAdapter(R.layout.item_movie, getApplicationContext());
        recyclerView.setAdapter(movieAdapter);
        recyclerView.setLayoutManager(linearLayoutManager);
        fetchData();
    }

    private void fetchData() {
        progressBar.setVisibility(View.VISIBLE);
        Log.i("progress bar", "called");
        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
        Call<MovieResponse> call = apiInterface.getTopRatedMovies(API_KEY, currentPage);

        call.enqueue(new Callback<MovieResponse>() {
            @Override
            public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
                List<Movie> movies = response.body().getResults();
                movieAdapter.addAll(movies);

                recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                    @Override
                    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                        super.onScrollStateChanged(recyclerView, newState);
                        if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
                            isScrolling = true;
                        }
                    }

                    @Override
                    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                        super.onScrolled(recyclerView, dx, dy);
                        currentItems = linearLayoutManager.getChildCount();
                        totalItems = linearLayoutManager.getItemCount();
                        scrollOutItems = linearLayoutManager.findFirstVisibleItemPosition();

                        if(isScrolling & (currentItems + scrollOutItems == totalItems)){
                            isScrolling = false;
                            currentPage += 1;
                            fetchData();
                        }
                    }
                });
                progressBar.setVisibility(View.GONE);
            }

            @Override
            public void onFailure(Call<MovieResponse> call, Throwable t) {
                Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

}

MovieAdapter.java

package technology.nine.moviedb.adapter;

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

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;

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

import technology.nine.moviedb.GlideApp;
import technology.nine.moviedb.R;
import technology.nine.moviedb.api.ApiClient;
import technology.nine.moviedb.model.Movie;

/**
 * Created by Ganesh on 25-02-2018.
 */

public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> {

    private List<Movie> movies;
    private int rowLayout;
    private Context context;

    public MovieAdapter(int rowLayout, Context context) {
        movies = new ArrayList<>();
        this.rowLayout = rowLayout;
        this.context = context;
    }

    @Override
    public MovieViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false);
        return new MovieViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MovieViewHolder holder, int position) {
        //holder.title.setText(movies.get(position).getTitle());

        String img_url_path = ApiClient.IMAGE_URL + movies.get(position).getPosterPath();

        GlideApp.with(context)
                .load(img_url_path)
                .override(holder.poster.getWidth(), holder.poster.getHeight())
                .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
                .into(holder.poster);
    }

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

    public class MovieViewHolder extends RecyclerView.ViewHolder {

        LinearLayout moviesLayout;
        ImageView poster;

        public MovieViewHolder(View v) {
            super(v);
            moviesLayout = (LinearLayout) v.findViewById(R.id.item_movie);
            poster = (ImageView) v.findViewById(R.id.image_view);
        }

    }

    public void addAll(List<Movie> movies) {
        for(Movie m: movies) {
            add(m);
        }
    }

    private void add(Movie m) {
        movies.add(m);
        notifyItemInserted(movies.size() - 1);
    }

}

这个项目的Github link

帮我解决此问题。提前谢谢。

3 个答案:

答案 0 :(得分:1)

因为你的列表是horzontal你应该知道match_parent给列表固定大小所以它将填充5项并且不再考虑使用wrap_content作为动态大小的空间

item_movie.xml

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:id="@+id/image_view"/>

wrap_content可能会起作用,具体取决于高度的情况,所以先检查一下

如果想要保持纵横比你可以使用零高度的重量android将完成工作

   <ImageView
    **android:scaleType="centerInside"**
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    />
  

机器人:scaleType =&#34; centerInside&#34;

将呈现图像以保持缩放

答案 1 :(得分:1)

一切似乎都很好。尝试修改onScrolled函数内的条件,如下所示:

int buffer = 3;//you can modify this accordingly.
if(isScrolling & (scrollOutItem > (totalItems - buffer))){
    //call fetchData();
}

答案 2 :(得分:0)

item_movie.xml

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:id="@+id/item_movie">

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

</LinearLayout>

设置布局的固定高度--------- 50dp,60dp,100dp等...