获取新数据后,应用程序始终转到第一页。因此,我必须(再次)滚动到底部才能在回收 View 上查看新数据。
代码
这是我的代码。我该如何解决我的问题?
package tonnyferiandi.lastproject;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
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.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class tab_feed extends Fragment {
private List<tab_feedItem> feedsList;
private RecyclerView mRecyclerView;
private tab_feedAdapter adapter;
private ProgressBar progressBar;
private Bitmap photone;
private Bitmap photono;
private boolean load = true;
public int page=0;
public View v;
public String url;
LinearLayoutManager layoutManager;
int pastVisiblesItems, visibleItemCount, totalItemCount;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_tab_feed, container, false);
mRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(layoutManager);
progressBar = (ProgressBar) v.findViewById(R.id.progress_bar);
progressBar.setVisibility(View.VISIBLE);
feedsList = new ArrayList<>();
// Downloading data from below url
url = "http://tukoe.com/feed/getfeed.php?page="+String.valueOf(page);
new AsyncHttpTask().execute(url);
return v;
}
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
@Override
protected void onPreExecute() {
//setProgressBarIndeterminateVisibility(true);
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d("RecyclerView", e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
@Override
protected void onPostExecute(Integer result) {
// Download complete. Let us update UI
progressBar.setVisibility(View.GONE);
if (result == 1) {
scroll();
page++;
} else {
Toast.makeText(getActivity().getApplicationContext(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
}
}
}
private void parseResult(String result) {
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.optJSONArray("result");
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
tab_feedItem item = new tab_feedItem();
if(!post.getString("title").equals(null)){
load = true;
}
item.setTitle(post.optString("title"));
photone = decodeBase64(post.optString("photo"));
int outWidth;
int outHeight;
int inWidth = photone.getWidth();
int inHeight = photone.getHeight();
if(inWidth > inHeight){
outWidth = 768;
outHeight = (inHeight * 768) / inWidth;
} else {
outHeight = 768;
outWidth = (inWidth * 768) / inHeight;
}
photono = Bitmap.createScaledBitmap(photone, outWidth, outHeight, false);
item.setThumbnail(photono);
feedsList.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public static Bitmap decodeBase64(String input){
byte[] decodeByte = Base64.decode(input, 0);
return BitmapFactory.decodeByteArray(decodeByte, 0, decodeByte.length);
}
public void scroll(){
adapter = new tab_feedAdapter(getActivity(), feedsList);
mRecyclerView.setAdapter(adapter);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) //check for scroll down
{
visibleItemCount = mRecyclerView.getChildCount();
totalItemCount = layoutManager.getItemCount();
pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();
if (load) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
load = false;
url = "http://tukoe.com/feed/getfeed.php?page="+String.valueOf(page);
new AsyncHttpTask().execute(url);
}
}
}
}
});
}
}
问题
我必须更改哪一部分?
哪个部分使它进入顶部/首页或回收 View 上的第一个数据?
最佳答案
当您完成获取新数据时,您似乎正在重新创建适配器。这就是导致您滚动回到顶部的原因。我建议不要重新创建适配器,而是更新项目并将更改通知适配器。
首先,我想指出您正在从 AsyncTask 中引用 Fragment 中的数据。这是一个坏主意,因为它可能会导致并发问题。您的 AsyncTask 应该只引用它自己的变量。我建议您的 AsyncTask 结果返回一个 tab_feed 项目列表,您可以使用它来更新您的 UI。
首先,您应该只在创建 Fragment 时调用 scroll()
方法一次。初始化适配器时可以使用空数组,因为无论如何我们很快就会更新它们。
获取完成后在您的 fragment 中:
@Override
protected void onPostExecute(List<tab_feedItem> result) {
// Download complete. Let us update UI
progressBar.setVisibility(View.GONE);
if (result != null) {
adapter.updateItems(result);
adapter.notifyDataSetChanged();
} else {
Toast.makeText(getActivity().getApplicationContext(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
}
}
在你的适配器内部:
public void updateItems(List<tab_feedItem> feedItems){
this.items.clear();
this.items.addAll(feeditems);
}
这应该可以解决您遇到的问题。更快的解决方案是保存滚动位置并在重新创建适配器后再次加载它。我建议不要这样做,因为它不能解决你潜在的并发问题,而且很草率。上述建议将需要对您的代码进行一些重大更改,但这是实现您尝试执行的操作的更正确方法。祝你好运!
关于Java Android 滚动到底部并获取新数据后总是转到第一个数据/页面(顶部回收 View ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37771894/