- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想在 recyclerview
中实现无限滚动,方法是调用带有页码增量的新 JSON 请求并将这些结果与之前的结果相加。第一个请求显示 20 个结果,但还有 200 多个结果要显示。如何使用“TopratedFragment.java”中的 onLoadMore()
函数进行无限滚动。请帮助代码
TopratedFragment.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.JsonObjectRequest;
import com.example.mitab.mentor.Movies.Pages.L;
import com.example.mitab.mentor.Movies.Pages.MyApplication;
import com.example.mitab.mentor.Movies.Pages.VolleySingleton;
import com.example.mitab.mentor.Movies.Pages.movie;
import com.example.mitab.mentor.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import android.os.Handler;
import static com.example.mitab.mentor.Movies.Pages.Keys.EndpointToprated.*;
/**
* A simple {@link Fragment} subclass.
* Use the {@link TopratedFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class TopratedFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
public static final String Top_rated="http://api.themoviedb.org/3/movie/top_rated";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
protected Handler handler;
private VolleySingleton volleySingleton;
private ImageLoader imageLoader;
int page=1;
private RequestQueue requestQueue;
private ArrayList<movie> listMovies=new ArrayList<>();
private ArrayList<movie> newlistMovies=new ArrayList<>();
private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
private RecyclerView listMovieHits;
private AdapterToprated adapterToprated;
boolean loadingMore = false;
private int lastVisibleItemId=0;
public TopratedFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static TopratedFragment newInstance(String param1, String param2) {
TopratedFragment fragment = new TopratedFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
volleySingleton= VolleySingleton.getsInstance();
requestQueue=volleySingleton.getRequestQueue();
sendJsonRequest();
}
private void sendJsonRequest(){
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, getRequestUrl(page), (String)null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
listMovies=parseJSONResponse(response);
adapterToprated.setMovieList(listMovies);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(request);
}
private ArrayList<movie> parseJSONResponse(JSONObject response){
ArrayList<movie> listMovies=new ArrayList<>();
if (response==null || response.length()>0){
try {
JSONArray arrayMovies=response.getJSONArray(KEY_MOVIES);
for (int i=0;i<arrayMovies.length();i++){
long id=-1;
String title="NA";
String poster="NA";
String release="NA";
String overview="NA";
String vote="NA";
String votecount="NA";
JSONObject currentMovie=arrayMovies.getJSONObject(i);
//get the id of current movie
if (currentMovie.has(KEY_ID)&& !currentMovie.isNull(KEY_ID)){
id=currentMovie.getLong(KEY_ID);
}
if (currentMovie.has(KEY_TITLE)&& !currentMovie.isNull(KEY_TITLE)){
title=currentMovie.getString(KEY_TITLE);
}
if (currentMovie.has(KEY_POSTER_PATH)&& !currentMovie.isNull(KEY_POSTER_PATH)){
poster=currentMovie.getString(KEY_POSTER_PATH);
}
if (currentMovie.has(KEY_RELEASE_DATE)&& !currentMovie.isNull(KEY_RELEASE_DATE)){
release=currentMovie.getString(KEY_RELEASE_DATE);
}
if (currentMovie.has(KEY_OVERVIEW)&& !currentMovie.isNull(KEY_OVERVIEW)){
overview=currentMovie.getString(KEY_OVERVIEW);
}
if (currentMovie.has(KEY_AVERAGE_VOTE)&& !currentMovie.isNull(KEY_AVERAGE_VOTE)){
vote=currentMovie.getString(KEY_AVERAGE_VOTE);
}
if (currentMovie.has(KEY_VOTE_COUNT)&& !currentMovie.isNull(KEY_VOTE_COUNT)){
votecount=currentMovie.getString(KEY_VOTE_COUNT);
}
JSONArray genre=currentMovie.getJSONArray(KEY_GENRE_IDS);
if (currentMovie.has(KEY_GENRE_IDS)&& !currentMovie.isNull(KEY_GENRE_IDS)){
for (int j=0;j<genre.length();j++){
try {
String itemInArray=genre.getString(j);
}
catch (JSONException e){
}
}
}
movie movie=new movie();
movie.setId(id);
movie.setTitle(title);
movie.setOverview(overview);
movie.setAveragevote(vote);
Date date=null;
try {
date=dateFormat.parse(release);
}
catch (ParseException e){
}
movie.setReleasedate(date);
movie.setImage(poster);
movie.setVotecount(votecount);
if (id!=-1 && !title.equals("NA"))
{
listMovies.add(movie);
}
}
}
catch (JSONException e){
}
}
return listMovies;
}
public static String getRequestUrl(int page){
return Top_rated +"?api_key="+ MyApplication.API_KEY + "&page="+page;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_toprated, container, false);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
handler=new Handler();
listMovieHits=(RecyclerView) view.findViewById(R.id.listMovieHits);
listMovieHits.setLayoutManager(linearLayoutManager);
adapterToprated=new AdapterToprated(getActivity());
listMovieHits.setAdapter(adapterToprated);
//sendJsonRequest();
// Add the scroll listener
listMovieHits.addOnScrollListener(new EndlessRecyclerViewScrollListener(linearLayoutManager) {
@Override
public void onLoadMore(int page, int totalItemsCount) {
loadingMore=true;
sendJsonRequest();
int curlsize=adapterToprated.getItemCount();
listMovies.addAll(newlistMovies);
adapterToprated.notifyItemRangeChanged(curlsize,listMovies.size()-2);
}
});
// Inflate the layout for this fragment
return view;
}
}
AdapterToprated.java
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.example.mitab.mentor.MainActivity;
import com.example.mitab.mentor.Movies.Pages.L;
import com.example.mitab.mentor.Movies.Pages.VolleySingleton;
import com.example.mitab.mentor.Movies.Pages.movie;
import com.example.mitab.mentor.R;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class AdapterToprated extends RecyclerView.Adapter<AdapterToprated.ViewHolderToprated> {
private LayoutInflater layoutInflater;
private VolleySingleton volleySingleton;
private ImageLoader imageLoader;
private ArrayList<movie> listMovies=new ArrayList<movie>();
private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
private RecyclerView.OnItemTouchListener onItemTouchListener;
Context context;
public AdapterToprated(Context context){
layoutInflater=LayoutInflater.from(context);
volleySingleton=VolleySingleton.getsInstance();
imageLoader=volleySingleton.getImageLoader();
this.context = context;
}
public void setMovieList(ArrayList<movie> listMovies){
this.listMovies=listMovies;
notifyItemRangeChanged(0, listMovies.size());
}
@Override
public ViewHolderToprated onCreateViewHolder(ViewGroup parent, int viewType) {
View view=layoutInflater.inflate(R.layout.individual_toprated, parent, false);
ViewHolderToprated viewHolderToprated=new ViewHolderToprated(view);
return viewHolderToprated;
}
@Override
public void onBindViewHolder(final ViewHolderToprated holder, int position) {
final movie currentMovie=listMovies.get(position);
holder.movieTitle.setText(currentMovie.getTitle());
Date movieReleaseDate=currentMovie.getReleasedate();
if (movieReleaseDate!=null){
String formattedDate=dateFormat.format(movieReleaseDate);
holder.movieReleaseDate.setText(formattedDate);
}else{
holder.movieReleaseDate.setText("NA");
}
holder.movieRating.setText(currentMovie.getAveragevote());
String urlThumnail=currentMovie.getImage();
if (!urlThumnail.equals("NA")){
imageLoader.get(urlThumnail, new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
holder.movieThumbnail.setImageBitmap(response.getBitmap());
}
@Override
public void onErrorResponse(VolleyError error) {
}
});
}
holder.lnrLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(context,Intentpass.class);
Bundle extras=new Bundle();
extras.putString("Title","currentMovie.getTitle()");
extras.putString("Date","formattedDate");
extras.putString("Rating","currentMovie.getAveragevote()");
intent.putExtras(extras);
context.startActivity(intent);
//intent.putExtra("details",currentMovie.getTitle());
//context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return listMovies.size();
}
static class ViewHolderToprated extends RecyclerView.ViewHolder{
private ImageView movieThumbnail;
private TextView movieTitle;
private TextView movieReleaseDate;
private TextView movieRating;
private RelativeLayout lnrLayout;
public ViewHolderToprated(View itemView) {
super(itemView);
movieThumbnail=(ImageView) itemView.findViewById(R.id.movieThumbnail);
movieTitle=(TextView) itemView.findViewById(R.id.movieTitle);
movieReleaseDate=(TextView) itemView.findViewById(R.id.movieReleaseDate);
movieRating=(TextView) itemView.findViewById(R.id.movieRating);
lnrLayout=(RelativeLayout)itemView.findViewById(R.id.lnLayout);
}
}
}
EndlessRecyclerViewScrollListener.java
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 5;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private int startingPageIndex = 0;
RecyclerView.LayoutManager mLayoutManager;
public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
}
public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
}
public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
}
public int getLastVisibleItem(int[] lastVisibleItemPositions) {
int maxSize = 0;
for (int i = 0; i < lastVisibleItemPositions.length; i++) {
if (i == 0) {
maxSize = lastVisibleItemPositions[i];
}
else if (lastVisibleItemPositions[i] > maxSize) {
maxSize = lastVisibleItemPositions[i];
}
}
return maxSize;
}
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScrolled(RecyclerView view, int dx, int dy) {
int lastVisibleItemPosition = 0;
int totalItemCount = mLayoutManager.getItemCount();
if (mLayoutManager instanceof StaggeredGridLayoutManager) {
int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);
// get maximum element within the list
lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
} else if (mLayoutManager instanceof LinearLayoutManager) {
lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
} else if (mLayoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if (loading && (totalItemCount > previousTotalItemCount)) {
loading = false;
previousTotalItemCount = totalItemCount;
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
// threshold should reflect how many total columns there are too
if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
currentPage++;
onLoadMore(currentPage, totalItemCount);
loading = true;
}
}
// Defines the process for actually loading more data based on page
public abstract void onLoadMore(int page, int totalItemsCount);
}
最佳答案
您只需将新数据添加到列表电影的最后位置,一切都会正常进行。为此——
创建一个新列表,如 ArrayList
ArrayList<movie> newListMovies = new ArrayList<>();
// your code..
listMovieHits.addOnScrollListener(new EndlessRecyclerViewScrollListener(linearLayoutManager) {
@Override
public void onLoadMore(int page, int totalItemsCount) {
loadingMore=true;
sendJsonRequest();
int currentSize = adapter.getItemCount();
listMovies.addAll(newListMovies);
adapter.notifyItemRangeInserted(currentSize, listMovies.size() - 2);
}
});
希望对您有所帮助。
关于android - 通过 Json 请求在 recyclerview 中连续滚动并添加新项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35816701/
最近开始学习MongoDB。今天老师教了我们 mongoexport 命令。在练习时,我遇到了一个典型的问题,包括教练在内的其他同学都没有遇到过。我在我的 Windows 10 机器上使用 Mongo
我是 JSON Schema 的新手,读过什么是 JSON Schema 等等。但我不知道如何将 JSON Schema 链接到 JSON 以针对该 JSON Schema 进行验证。谁能解释一下?
在 xml 中,我可以在另一个 xml 文件中包含一个文件并使用它。如果您的软件从 xml 获取配置文件但没有任何方法来分离配置,如 apache/ngnix(nginx.conf - site-av
我有一个 JSON 对象,其中包含一个本身是 JSON 对象的字符串。我如何反序列化它? 我希望能够做类似的事情: #[derive(Deserialize)] struct B { c: S
考虑以下 JSON { "a": "{\"b\": 12, \"c\": \"test\"}" } 我想定义一个泛型读取 Reads[Outer[T]]对于这种序列化的 Json import
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 11 个月前关闭。 Improve
我的旧项目在 MySQL 中有 Standard JSON 格式的数据。 对于我在 JS (Node.js) 和 DynamoDB 中的全新项目,关于 Standard JSON格式: 是否建议将其转
JSON 值字符串、数字、true、false、null 是否是有效的 JSON? 即,是 true 一个有效的 JSON 文档?还是必须是数组/对象? 一些验证器接受这个(例如 http://jso
我有一个 JSON 字符串,其中一个字段是文本字段。这个文本字段可以包含用户在 UI 中输入的文本,如果他们输入的文本是 JSON 文本,也许是为了说明一些编码,我需要对他们的文本进行编码,以便它不会
我正在通过 IBM MQ 调用处理数据,当由 ColdFusion 10 (10,0,11,285437) 序列化时,0 将作为 +0.0 返回,它会导致无效的 JSON并且无法反序列化。 stPol
我正在从三个数组中生成一个散列,然后尝试构建一个 json。我通过 json object has array 成功了。 require 'json' A = [['A1', 'A2', 'A3'],
我从 API 接收 JSON,响应可以是 30 种类型之一。每种类型都有一组唯一的字段,但所有响应都有一个字段 type 说明它是哪种类型。 我的方法是使用serde .我为每种响应类型创建一个结构并
我正在下载一个 JSON 文件,我已将其检查为带有“https://jsonlint.com”的有效 JSON 到文档目录。然后我打开文件并再次检查,结果显示为无效的 JSON。这怎么可能????这是
我正在尝试根据从 API 接收到的数据动态创建一个 JSON 对象。 收到的示例数据:将数据解码到下面给出的 CiItems 结构中 { "class_name": "test", "
我想从字符串转换为对象。 来自 {"key1": "{\n \"key2\": \"value2\",\n \"key3\": {\n \"key4\": \"value4\"\n }\n
目前我正在使用以下代码将嵌套的 json 转换为扁平化的 json: import ( "fmt" "github.com/nytlabs/gojsonexplode" ) func
我有一个使用来自第三方 API 的数据的应用程序。我需要将 json 解码为一个结构,这需要该结构具有“传入”json 字段的 json 标签。传出的 json 字段具有不同的命名约定,因此我需要不同
我想使用 JSON 架构来验证某些值。我有两个对象,称它们为 trackedItems 和 trackedItemGroups。 trackedItemGroups 是组名称和 trackedItem
考虑以下案例类模式, case class Y (a: String, b: String) case class X (dummy: String, b: Y) 字段b是可选的,我的一些数据集没有字
我正在存储 cat ~/path/to/file/blah | 的输出jq tojson 在一个变量中,稍后在带有 JSON 内容的 curl POST 中使用。它运作良好,但它删除了所有换行符。我知
我是一名优秀的程序员,十分优秀!