无尽的 recyclerview 以及在 recyclerview 中从服务器加载滚动使用 cardview 加载图像和文本
endless recyclerview along with load onscroll from server in recyclerview using cardview to load images and text
我已经使用 cardview 实现了 recyclerview,以使用本教程从我的服务器获取图像和文本:http://www.simplifiedcoding.net/android-custom-listview-with-images-using-recyclerview-and-volley/。
我已成功获取数据并根据我的要求修改了代码,现在我想实现类似于Instagram应用程序的滑动刷新和无限滚动。我已经尝试了很多教程和 SO 问题,但是我无法实现其中任何一个。
我部分成功地实现了滑动刷新,但应用程序退出并显示 inconsistency error
。请指导
MainActivity.java
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener{
SwipeRefreshLayout swipeLayout;
LinearLayoutManager mLayoutManager;
// initially offset will be 0, later will be updated while parsing the json
private int offSet = 0;
private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
//Creating a List of superheroes
private List<SuperHeroes> listSuperHeroes;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
public String Img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//Initializing our superheroes list
listSuperHeroes = new ArrayList<>();
mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
swipeLayout.post(new Runnable() {
@Override
public void run() {
swipeLayout.setRefreshing(true);
getData();
}
}
);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) //check for scroll down
{
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
Log.v("...", "Last Item Wow !");
//Do pagination.. i.e. fetch new data
loading = true;
}
}
}
}
});
}
//This method will get data from the web api
private void getData(){
//Showing a progress dialog
// final ProgressDialog loading = ProgressDialog.show(this,"Loading Data", "Please wait...",false,false);
// appending offset to url
String url = Config.DATA_URL;
String url1 = url + offSet;
//Creating a json array request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url1,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
//Dismissing progress dialog
// loading.dismiss();
//calling method to parse json array
parseData(response);
adapter.notifyDataSetChanged();
// stopping swipe refresh
swipeLayout.setRefreshing(false);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonArrayRequest);
}
//This method will parse json data
private void parseData(JSONArray array){
for(int i = 0; i<array.length(); i++) {
SuperHeroes superHero = new SuperHeroes();
CardAdapter car = new CardAdapter();
JSONObject json = null;
try {
json = array.getJSONObject(i);
superHero.setImageUrl(json.getString(Config.TAG_IMAGE_URL));
Img =json.getString(Config.TAG_IMAGE_URL);
superHero.setName(json.getString(Config.TAG_NAME));
superHero.setRank(json.getInt(Config.TAG_RANK));
// superHero.setRealName(json.getString(Config.TAG_REAL_NAME));
//superHero.setCreatedBy(json.getString(Config.TAG_CREATED_BY));
//superHero.setFirstAppearance(json.getString(Config.TAG_FIRST_APPEARANCE));
int rank = json.getInt("pid");
// updating offset value to highest value
if (rank >= offSet)
offSet = rank;
// ArrayList<String> powers = new ArrayList<String>();
//JSONArray jsonArray = json.getJSONArray(Config.TAG_POWERS);
/* for(int j = 0; j<jsonArray.length(); j++){
powers.add(((String) jsonArray.get(j))+"\n");
}*/
//superHero.setPowers(powers);
Log.d("test",Img);
car.setImageUrl(Img);
} catch (JSONException e) {
e.printStackTrace();
}
listSuperHeroes.add(superHero);
}
//Finally initializing our adapter
adapter = new CardAdapter(listSuperHeroes, this);
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
}
@Override
public void onRefresh() {
listSuperHeroes.clear();
getData();
}
}
CardAdapter.java
/**
* Created by Belal on 11/9/2015.
*/
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
private String imageUrl;
private ImageLoader imageLoader;
private Context context;
String Load;
static int count = 0;
public static final String uu = "uu";
String number;
String user1;
public static final String UserNum = "UserNum";
SharedPreferences sharedPref;
// JSON parser class
JSONParser jsonParser = new JSONParser();
//testing from a real server:
private static final String LIKE_URL = "myurl";
//ids
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
//List of superHeroes
List<SuperHeroes> superHeroes;
public CardAdapter() {
}
public CardAdapter(List<SuperHeroes> superHeroes, Context context) {
super();
//Getting all the superheroes
this.superHeroes = superHeroes;
this.context = context;
sharedPref =context.getSharedPreferences(UserNum, 0);
number = sharedPref.getString(uu, "");
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.superheroes_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
SuperHeroes superHero = superHeroes.get(position);
Log.d("position", String.valueOf(position));
Log.d("url", superHero.getImageUrl());
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
imageLoader.get(superHero.getImageUrl(), ImageLoader.getImageListener(holder.imageView, R.mipmap.ic_launcher, android.R.drawable.ic_dialog_alert));
holder.imageView.setImageUrl(superHero.getImageUrl(), imageLoader);
holder.textViewName.setText(superHero.getName());
holder.textViewRank.setText(String.valueOf(superHero.getRank()));
// holder.textViewRealName.setText(superHero.getRealName());
// holder.textViewCreatedBy.setText(superHero.getCreatedBy());
// holder.textViewFirstAppearance.setText(superHero.getFirstAppearance());
// Load =superHero.getImageUrl();
// String powers = "";
// for(int i = 0; i<superHero.getPowers().size(); i++){
// powers+= superHero.getPowers().get(i);
// }
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
count++;
ViewHolder h = (ViewHolder) view.getTag();
// int p=h.getAdapterPosition();
SuperHeroes s = superHeroes.get(position);
// Toast.makeText(context,s.getImageUrl(),Toast.LENGTH_LONG).show();
Load = s.getImageUrl();
Log.d("test", Load);
String s1 = new Integer(count).toString();
Log.d("count", s1);
new LikeIt().execute();
}
};
// holder.textViewPowers.setText(powers);
holder.like.setOnClickListener(clickListener);
}
@Override
public int getItemCount() {
return superHeroes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public NetworkImageView imageView;
public TextView textViewName;
public TextView textViewRank;
public TextView textViewRealName;
public TextView textViewCreatedBy;
public TextView textViewFirstAppearance;
public TextView textViewPowers;
public Button like;
public ViewHolder(View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
textViewRank = (TextView) itemView.findViewById(R.id.textViewRank);
// textViewRealName= (TextView) itemView.findViewById(R.id.textViewRealName);
// textViewCreatedBy= (TextView) itemView.findViewById(R.id.textViewCreatedBy);
// textViewFirstAppearance= (TextView) itemView.findViewById(R.id.textViewFirstAppearance);
// textViewPowers= (TextView) itemView.findViewById(R.id.textViewPowers);
like = (Button) itemView.findViewById(R.id.button_like);
}
}
class LikeIt extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
*/
boolean failure = false;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... args) {
// TODO Auto-generated method stub
// Check for success tag
int success;
String Imgurl = Load;
Log.d("request!", number);
// try {
// Building Parameters
HashMap<String, String> Params = new HashMap<String, String>();
Params.put("Imgurl", Imgurl);
Params.put("user", number);
Log.d("request!", "starting");
//Posting user data to script
/* JSONObject json = jsonParser.performPostCall(LIKE_URL,Params);
// full json response
Log.d("Login attempt", json.toString());
// json success element
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
Log.d("User Created!", json.toString());
//finish();
return json.getString(TAG_MESSAGE);
}else{
Log.d("Login Failure!", json.getString(TAG_MESSAGE));
return json.getString(TAG_MESSAGE);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;*/
String encodedStr = getEncodedData(Params);
//Will be used if we want to read some data from server
BufferedReader reader = null;
//Connection Handling
try {
//Converting address String to URL
URL url = new URL(LIKE_URL);
//Opening the connection (Not setting or using CONNECTION_TIMEOUT)
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//Post Method
con.setRequestMethod("POST");
//To enable inputting values using POST method
//(Basically, after this we can write the dataToSend to the body of POST method)
con.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
//Writing dataToSend to outputstreamwriter
writer.write(encodedStr);
//Sending the data to the server - This much is enough to send data to server
//But to read the response of the server, you will have to implement the procedure below
writer.flush();
//Data Read Procedure - Basically reading the data comming line by line
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while((line = reader.readLine()) != null) { //Read till there is something available
sb.append(line + "\n"); //Reading and saving line by line - not all at once
}
line = sb.toString(); //Saving complete data received in string, you can do it differently
//Just check to the values received in Logcat
Log.i("custom_check","The values :");
Log.i("custom_check",line);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader != null) {
try {
reader.close(); //Closing the
} catch (IOException e) {
e.printStackTrace();
}
}
}
//Same return null, but if you want to return the read string (stored in line)
//then change the parameters of AsyncTask and return that type, by converting
//the string - to say JSON or user in your case
return null;
}
}
private String getEncodedData(Map<String,String> data) {
StringBuilder sb = new StringBuilder();
for(String key : data.keySet()) {
String value = null;
try {
value = URLEncoder.encode(data.get(key), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if(sb.length()>0)
sb.append("&");
sb.append(key + "=" + value);
}
return sb.toString();
}
/**
* After completing background task Dismiss the progress dialog
**/
protected void onPostExecute() {
// dismiss the dialog once product deleted
}
}
在刷新时滑动时,如果我在刷新后立即向下滚动,应用程序会崩溃,但如果我等到刷新发生,我不会收到不一致错误
Logcat错误
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: FATAL EXCEPTION: main
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: Process: com.example.tatson.bila, PID: 14987
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{278460a2 position=3 id=-1, oldPos=-1, pLpos:-1 no parent}
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:4247)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4378)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4359)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1961)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1370)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1333)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1161)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1018)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:3807)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:580)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:549)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.os.Looper.loop(Looper.java:135)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5253)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
当我快速滚动到末尾而不是当我在最后一个项目上向下滚动时,滚动负载也会被激活
提前致谢!!! :)
分页背后的概念:
- 您将额外的 variable/value 传递给后端(在您的情况下 PHP)假设 "last_seen"。对于值的初始获取,您会将
last_seen
值作为 0 传递,这意味着 php 将具有在此值达到某个限制后获取值的逻辑(例如 PHP 将发送结果从索引 1 到 20 到 android。
- 正如您所知,您的上限是 20,因此下次在
RecyclerView.OnScrollListener
中的页面加载时,您将再次调用 PHP。但这次您的 last_seen
将为 20,而 PHP 将为您提供从 21 到 40 的结果,依此类推。
滑动刷新的概念:
在实现滑动刷新时,它有一个名为 onRefresh()
的方法,您将在此处应用初始 PHP 调用,其中 last_seen
为 0,它将获取初始数据来自后端。
要实现,请访问以下链接:
我还写了一个新博客 post 来满足您在这里提出的要求。
检查此 Android Feed Example。
您必须在您的服务器上创建一个分页脚本。我使用了以下代码。
<?php
//Getting the page number which is to be displayed
$page = $_GET['page'];
//Initially we show the data from 1st row that means the 0th row
$start = 0;
//Limit is 3 that means we will show 3 items at once
$limit = 3;
//Importing the database connection
require_once('dbConnect.php');
//Counting the total item available in the database
$total = mysqli_num_rows(mysqli_query($con, "SELECT id from feed "));
//We can go atmost to page number total/limit
$page_limit = $total/$limit;
//If the page number is more than the limit we cannot show anything
if($page<=$page_limit){
//Calculating start for every given page number
$start = ($page - 1) * $limit;
//SQL query to fetch data of a range
$sql = "SELECT * from feed limit $start, $limit";
//Getting result
$result = mysqli_query($con,$sql);
//Adding results to an array
$res = array();
while($row = mysqli_fetch_array($result)){
array_push($res, array(
"name"=>$row['name'],
"publisher"=>$row['publisher'],
"image"=>$row['image'])
);
}
//Displaying the array in json format
echo json_encode($res);
}else{
echo "over";
}
其余相同..另外我添加了一个侦听器以在到达列表底部后加载列表中的更多记录。
我已经使用 cardview 实现了 recyclerview,以使用本教程从我的服务器获取图像和文本:http://www.simplifiedcoding.net/android-custom-listview-with-images-using-recyclerview-and-volley/。
我已成功获取数据并根据我的要求修改了代码,现在我想实现类似于Instagram应用程序的滑动刷新和无限滚动。我已经尝试了很多教程和 SO 问题,但是我无法实现其中任何一个。
我部分成功地实现了滑动刷新,但应用程序退出并显示 inconsistency error
。请指导
MainActivity.java
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener{
SwipeRefreshLayout swipeLayout;
LinearLayoutManager mLayoutManager;
// initially offset will be 0, later will be updated while parsing the json
private int offSet = 0;
private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
//Creating a List of superheroes
private List<SuperHeroes> listSuperHeroes;
//Creating Views
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
public String Img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initializing Views
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
//Initializing our superheroes list
listSuperHeroes = new ArrayList<>();
mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorSchemeResources(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
swipeLayout.post(new Runnable() {
@Override
public void run() {
swipeLayout.setRefreshing(true);
getData();
}
}
);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) //check for scroll down
{
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
Log.v("...", "Last Item Wow !");
//Do pagination.. i.e. fetch new data
loading = true;
}
}
}
}
});
}
//This method will get data from the web api
private void getData(){
//Showing a progress dialog
// final ProgressDialog loading = ProgressDialog.show(this,"Loading Data", "Please wait...",false,false);
// appending offset to url
String url = Config.DATA_URL;
String url1 = url + offSet;
//Creating a json array request
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url1,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
//Dismissing progress dialog
// loading.dismiss();
//calling method to parse json array
parseData(response);
adapter.notifyDataSetChanged();
// stopping swipe refresh
swipeLayout.setRefreshing(false);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonArrayRequest);
}
//This method will parse json data
private void parseData(JSONArray array){
for(int i = 0; i<array.length(); i++) {
SuperHeroes superHero = new SuperHeroes();
CardAdapter car = new CardAdapter();
JSONObject json = null;
try {
json = array.getJSONObject(i);
superHero.setImageUrl(json.getString(Config.TAG_IMAGE_URL));
Img =json.getString(Config.TAG_IMAGE_URL);
superHero.setName(json.getString(Config.TAG_NAME));
superHero.setRank(json.getInt(Config.TAG_RANK));
// superHero.setRealName(json.getString(Config.TAG_REAL_NAME));
//superHero.setCreatedBy(json.getString(Config.TAG_CREATED_BY));
//superHero.setFirstAppearance(json.getString(Config.TAG_FIRST_APPEARANCE));
int rank = json.getInt("pid");
// updating offset value to highest value
if (rank >= offSet)
offSet = rank;
// ArrayList<String> powers = new ArrayList<String>();
//JSONArray jsonArray = json.getJSONArray(Config.TAG_POWERS);
/* for(int j = 0; j<jsonArray.length(); j++){
powers.add(((String) jsonArray.get(j))+"\n");
}*/
//superHero.setPowers(powers);
Log.d("test",Img);
car.setImageUrl(Img);
} catch (JSONException e) {
e.printStackTrace();
}
listSuperHeroes.add(superHero);
}
//Finally initializing our adapter
adapter = new CardAdapter(listSuperHeroes, this);
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
}
@Override
public void onRefresh() {
listSuperHeroes.clear();
getData();
}
}
CardAdapter.java
/**
* Created by Belal on 11/9/2015.
*/
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
private String imageUrl;
private ImageLoader imageLoader;
private Context context;
String Load;
static int count = 0;
public static final String uu = "uu";
String number;
String user1;
public static final String UserNum = "UserNum";
SharedPreferences sharedPref;
// JSON parser class
JSONParser jsonParser = new JSONParser();
//testing from a real server:
private static final String LIKE_URL = "myurl";
//ids
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
//List of superHeroes
List<SuperHeroes> superHeroes;
public CardAdapter() {
}
public CardAdapter(List<SuperHeroes> superHeroes, Context context) {
super();
//Getting all the superheroes
this.superHeroes = superHeroes;
this.context = context;
sharedPref =context.getSharedPreferences(UserNum, 0);
number = sharedPref.getString(uu, "");
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.superheroes_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
SuperHeroes superHero = superHeroes.get(position);
Log.d("position", String.valueOf(position));
Log.d("url", superHero.getImageUrl());
imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
imageLoader.get(superHero.getImageUrl(), ImageLoader.getImageListener(holder.imageView, R.mipmap.ic_launcher, android.R.drawable.ic_dialog_alert));
holder.imageView.setImageUrl(superHero.getImageUrl(), imageLoader);
holder.textViewName.setText(superHero.getName());
holder.textViewRank.setText(String.valueOf(superHero.getRank()));
// holder.textViewRealName.setText(superHero.getRealName());
// holder.textViewCreatedBy.setText(superHero.getCreatedBy());
// holder.textViewFirstAppearance.setText(superHero.getFirstAppearance());
// Load =superHero.getImageUrl();
// String powers = "";
// for(int i = 0; i<superHero.getPowers().size(); i++){
// powers+= superHero.getPowers().get(i);
// }
View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
count++;
ViewHolder h = (ViewHolder) view.getTag();
// int p=h.getAdapterPosition();
SuperHeroes s = superHeroes.get(position);
// Toast.makeText(context,s.getImageUrl(),Toast.LENGTH_LONG).show();
Load = s.getImageUrl();
Log.d("test", Load);
String s1 = new Integer(count).toString();
Log.d("count", s1);
new LikeIt().execute();
}
};
// holder.textViewPowers.setText(powers);
holder.like.setOnClickListener(clickListener);
}
@Override
public int getItemCount() {
return superHeroes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public NetworkImageView imageView;
public TextView textViewName;
public TextView textViewRank;
public TextView textViewRealName;
public TextView textViewCreatedBy;
public TextView textViewFirstAppearance;
public TextView textViewPowers;
public Button like;
public ViewHolder(View itemView) {
super(itemView);
imageView = (NetworkImageView) itemView.findViewById(R.id.imageViewHero);
textViewName = (TextView) itemView.findViewById(R.id.textViewName);
textViewRank = (TextView) itemView.findViewById(R.id.textViewRank);
// textViewRealName= (TextView) itemView.findViewById(R.id.textViewRealName);
// textViewCreatedBy= (TextView) itemView.findViewById(R.id.textViewCreatedBy);
// textViewFirstAppearance= (TextView) itemView.findViewById(R.id.textViewFirstAppearance);
// textViewPowers= (TextView) itemView.findViewById(R.id.textViewPowers);
like = (Button) itemView.findViewById(R.id.button_like);
}
}
class LikeIt extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
*/
boolean failure = false;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... args) {
// TODO Auto-generated method stub
// Check for success tag
int success;
String Imgurl = Load;
Log.d("request!", number);
// try {
// Building Parameters
HashMap<String, String> Params = new HashMap<String, String>();
Params.put("Imgurl", Imgurl);
Params.put("user", number);
Log.d("request!", "starting");
//Posting user data to script
/* JSONObject json = jsonParser.performPostCall(LIKE_URL,Params);
// full json response
Log.d("Login attempt", json.toString());
// json success element
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
Log.d("User Created!", json.toString());
//finish();
return json.getString(TAG_MESSAGE);
}else{
Log.d("Login Failure!", json.getString(TAG_MESSAGE));
return json.getString(TAG_MESSAGE);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;*/
String encodedStr = getEncodedData(Params);
//Will be used if we want to read some data from server
BufferedReader reader = null;
//Connection Handling
try {
//Converting address String to URL
URL url = new URL(LIKE_URL);
//Opening the connection (Not setting or using CONNECTION_TIMEOUT)
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//Post Method
con.setRequestMethod("POST");
//To enable inputting values using POST method
//(Basically, after this we can write the dataToSend to the body of POST method)
con.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
//Writing dataToSend to outputstreamwriter
writer.write(encodedStr);
//Sending the data to the server - This much is enough to send data to server
//But to read the response of the server, you will have to implement the procedure below
writer.flush();
//Data Read Procedure - Basically reading the data comming line by line
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while((line = reader.readLine()) != null) { //Read till there is something available
sb.append(line + "\n"); //Reading and saving line by line - not all at once
}
line = sb.toString(); //Saving complete data received in string, you can do it differently
//Just check to the values received in Logcat
Log.i("custom_check","The values :");
Log.i("custom_check",line);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader != null) {
try {
reader.close(); //Closing the
} catch (IOException e) {
e.printStackTrace();
}
}
}
//Same return null, but if you want to return the read string (stored in line)
//then change the parameters of AsyncTask and return that type, by converting
//the string - to say JSON or user in your case
return null;
}
}
private String getEncodedData(Map<String,String> data) {
StringBuilder sb = new StringBuilder();
for(String key : data.keySet()) {
String value = null;
try {
value = URLEncoder.encode(data.get(key), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if(sb.length()>0)
sb.append("&");
sb.append(key + "=" + value);
}
return sb.toString();
}
/**
* After completing background task Dismiss the progress dialog
**/
protected void onPostExecute() {
// dismiss the dialog once product deleted
}
}
在刷新时滑动时,如果我在刷新后立即向下滚动,应用程序会崩溃,但如果我等到刷新发生,我不会收到不一致错误
Logcat错误
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: FATAL EXCEPTION: main
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: Process: com.example.tatson.bila, PID: 14987
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{278460a2 position=3 id=-1, oldPos=-1, pLpos:-1 no parent}
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:4247)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4378)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4359)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1961)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1370)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1333)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1161)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1018)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:3807)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:580)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:549)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.os.Looper.loop(Looper.java:135)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5253)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
11-21 16:04:28.209 14987-14987/com.example.tatson.bila E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
当我快速滚动到末尾而不是当我在最后一个项目上向下滚动时,滚动负载也会被激活
提前致谢!!! :)
分页背后的概念:
- 您将额外的 variable/value 传递给后端(在您的情况下 PHP)假设 "last_seen"。对于值的初始获取,您会将
last_seen
值作为 0 传递,这意味着 php 将具有在此值达到某个限制后获取值的逻辑(例如 PHP 将发送结果从索引 1 到 20 到 android。 - 正如您所知,您的上限是 20,因此下次在
RecyclerView.OnScrollListener
中的页面加载时,您将再次调用 PHP。但这次您的last_seen
将为 20,而 PHP 将为您提供从 21 到 40 的结果,依此类推。
滑动刷新的概念:
在实现滑动刷新时,它有一个名为 onRefresh()
的方法,您将在此处应用初始 PHP 调用,其中 last_seen
为 0,它将获取初始数据来自后端。
要实现,请访问以下链接:
我还写了一个新博客 post 来满足您在这里提出的要求。 检查此 Android Feed Example。
您必须在您的服务器上创建一个分页脚本。我使用了以下代码。
<?php
//Getting the page number which is to be displayed
$page = $_GET['page'];
//Initially we show the data from 1st row that means the 0th row
$start = 0;
//Limit is 3 that means we will show 3 items at once
$limit = 3;
//Importing the database connection
require_once('dbConnect.php');
//Counting the total item available in the database
$total = mysqli_num_rows(mysqli_query($con, "SELECT id from feed "));
//We can go atmost to page number total/limit
$page_limit = $total/$limit;
//If the page number is more than the limit we cannot show anything
if($page<=$page_limit){
//Calculating start for every given page number
$start = ($page - 1) * $limit;
//SQL query to fetch data of a range
$sql = "SELECT * from feed limit $start, $limit";
//Getting result
$result = mysqli_query($con,$sql);
//Adding results to an array
$res = array();
while($row = mysqli_fetch_array($result)){
array_push($res, array(
"name"=>$row['name'],
"publisher"=>$row['publisher'],
"image"=>$row['image'])
);
}
//Displaying the array in json format
echo json_encode($res);
}else{
echo "over";
}
其余相同..另外我添加了一个侦听器以在到达列表底部后加载列表中的更多记录。