我想做什么?
垂直显示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。
帮我解决此问题。提前谢谢。
答案 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等...