PDA

View Full Version : رسیدن به انتهای لیست ویو و لود شدن ادامه ی مطالب



hosseinaryai
سه شنبه 25 آذر 1393, 11:52 صبح
سلام
من می خوام یه لیست ویو مثلن ده رکود اول دیتابیسو نشون بده و وقتی به انتها می رسه بره و مثلن ده رکورد بعدی رو نشون بده ..
به قسمت کوئری نوشتن و خروجی گرفتن مشکلی ندارم ..
گیرم زمانیه که به انتهای لیست ویو می رسم ..
خب دوست عزیزم Nevercom (http://barnamenevis.org/member.php?89707-Nevercom) لطف کردن و سه سایت زیر رو معرفی کردن :



http://benjii.me/2010/08/endless-scr...ew-in-android/ (http://benjii.me/2010/08/endless-scrolling-listview-in-android/)
http://mobile.dzone.com/news/android...ial-dynamicaly (http://mobile.dzone.com/news/android-tutorial-dynamicaly)
http://stackoverflow.com/questions/2...lling-listview (http://stackoverflow.com/questions/21945264/endless-scrolling-listview)


خودمم تو نت گشتم و نمونه برنامه هایی پیدا کردم ، اما موضوع اینجاست که اینا همشون زمانی درست کار می کنه که لیست ویو بصورت عادی و از پیش تعریف شده باشه .. وقتی لیست ویو رو سفارشی می کنم یکم گیج میشم .. نمی دونم باید چیکار کرد ..
(لیست ویو سفارشی من یه imaheview + textview یکی برای نشون دادن عکس و یکی هم برای نشون دادن اسمه)

ali_khodayar
سه شنبه 25 آذر 1393, 13:26 عصر
به نظر من لزومی نداره که کوئری بنویسی که 10 تا 10 تا اطلاعات رو بگیره و نمایش بده. خود ListView این کار رو انجام میده و فقط اطلاعاتی را نمایش میده که توی صفحه نمایش داده میشه . از این کار یه نمونه برنامه دارم که ListView ش هم تقریبأ سفارشیه. توی نت گشتم اما سایتش رو پیدا نکردم که لینکش رو بزارم . ایمیلت رو بزار تا برات بفرستم.

rubiks.kde
سه شنبه 25 آذر 1393, 14:28 عصر
هیچ فرقی نداره زمانی که لیست سفارسی میشه و از آداپتور خودتون استفاده میکنید.اگر از لیست شخصی شده نمیتونید استفاده کنید بهتره اول این موضوع رو حل کنید.




به نظر من لزومی نداره که کوئری بنویسی که 10 تا 10 تا اطلاعات رو بگیره و نمایش بده. خود ListView این کار رو انجام میده و فقط اطلاعاتی را نمایش میده که توی صفحه نمایش داده میشه . از این کار یه نمونه برنامه دارم که ListView ش هم تقریبأ سفارشیه. توی نت گشتم اما سایتش رو پیدا نکردم که لینکش رو بزارم . ایمیلت رو بزار تا برات بفرستم.

شاید متوجه منظور دوستمون نشده باشید ، لیست توسط آداپتور تغذیه میشه و اطلاعاتی رو نمایش میده که در آداپتور وجود داشته باشه پس مدیریت لود شدن اندک اندک ایتم ها دست برنامه نویس هست

Nevercom
سه شنبه 25 آذر 1393, 14:57 عصر
اصلاً تفاوتی نداره که چقدر لیست ویو رو سفارشی کرده باشه و چه آیتم هایی در هر ردیف نمایش داده میشه.

بسته به اینکه از کدوم View استفاده کنید (ListView, RecyclerView, GridView...)، متدهایی وجود داره برای اینکه متوجه بشید چه زمانی لیست به انتهای خودش رسیده.
در این مرحله باید دیتای جدید رو دریافت کنید و به آداپتور اضافه کنید (یعنی دیتای قبلی که در آداپتور هست رو داشته باشید و دیتای جدید رو بهش اضافه (Append) کنید.)

در لینک دوم می بینید که در متد onScroll هر لحظه محاسبه می کنه که آیا لیست به انتها (یا مکانی که مدنظر شما هست، مثلاً دوتا آیتم قبل از انتهای لیست) رسیده یا خیر. در این قسمت شما باید کد مربوط به دیافت دیتا و اضافه کردن به آداپتور رو بنویسید.

البته می تونید در خود آداپتور هم این رو پیاده سازی کنید، اما من ترجیح میدم آداپتور فقط وظیفه ی نمایش رو داشته باشه و دیتا رو خودم براش تامین کنم.

hosseinaryai
سه شنبه 25 آذر 1393, 17:26 عصر
ممنونم از همتون .. بازم تست می کنم و خبرشو میدم :لبخند:
دوست عزیزم ali_khodayar (http://barnamenevis.org/member.php?74193-ali_khodayar) ، گمان نمی کنم منظور من و تو در این مورد یکی باشه .. ولی این ایمیلمه ممنون میشم از زحمتت :
hosseinaryai@hotmail.com

hosseinaryai
سه شنبه 25 آذر 1393, 18:24 عصر
اوومممم .. اینجا گیر کردم ..
من اول توی onCreate به این صورت لیست ویوو رو پرش می کنم :

ArrayList<List_details> result1 = GetSearchResults();
list_sh.setAdapter(new List_adapt(result1,Page_shakhsi.this));
که به این متد وصله :

private static ArrayList<List_details> GetSearchResults() {
ArrayList<List_details> results = new ArrayList<List_details>();

loadingMore = true;
for(int i=0;i<MAX_ITEMS_PER_PAGE;i++)
{

list_shakhsi = new List_details();
list_shakhsi.setNamKol(ss1[i]);
list_shakhsi.setEmtKol(ss2[i]);

results.add(list_shakhsi);

}
loadingMore = false;
return results;
}



و در آخر هم توی رویداد onScroll به این صورت عمل می کنم


list_sh.setOnScrollListener(new OnScrollListener(){

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

int lastInScreen = firstVisibleItem + visibleItemCount;
//is the bottom item visible & not loading more already ? Load more !
if((lastInScreen == totalItemCount) && !(loadingMore)){

ArrayList<List_details> result1 = GetSearchResults();
list_sh.setAdapter(new List_adapt(result1,Page_shakhsi.this));
}
}

@Override
public void onScrollStateChanged(AbsListView arg0, int arg1) { }
});


اما این نمیره واسه ده تای بعدی .. همون ده تای اولی رو از اول لود می کنه و میره بالای صفحه ..
گمان نمی کنم کد زیر رو نباید توی onScroll بنویسم .. درسته ؟


ArrayList<List_details> result1 = GetSearchResults();
list_sh.setAdapter(new List_adapt(result1,Page_shakhsi.this));


اگر نه ، خب پس کد جایگزینش چی میشه ..:متفکر:

Nevercom
سه شنبه 25 آذر 1393, 19:14 عصر
آداپتور رو تغییر بدید
بجای اینکه دیتا رو در Constructor دریافت کنید، یک متد در آداپتور بسازید که دیتا رو دریافت کنه، مثلاً متدی با نام setData

یعنی این کد:
list_sh.setAdapter(new List_adapt(result1,Page_shakhsi.this));
به این شکل تغییر می کنه:

List_adapt adapter = new List_adapt(Page_shakhsi.this);
adapter.setData(result1);
list_sh.setAdapter(adapter);

حالا در متد onScroll از این کد استفاده کنید:
adapter.setData(GetSearchResults());
adapter.notifyDataSetChanged();
البته در این حالت هم فقط همون نتیجه ی جدید نمایش داده میشه، اما دلیلش این هست که شما باید دیتای جدید رو به دیتای قبلی اضافه کنید.
حالا یا باید دیتای قبلی رو در اکتیوتی ذخیره کنید و دیتای جدید رو بهش اضافه کنید و بفرستید به آداپتور، یا در متد setData مربوط به آداپتور کدی بنویسید که دیتای جدید رو درصورت وجود دیتای قبلی بهش اضافه کنه
من ساختار آداپتور شما رو نمیدونم، اما یک نمونه از این کد رو براتون می نویسم:
public void setData(List<Product> data, boolean addData) {
if (addData && this.mDataset != null) {
this.mDataset.addAll(data);
} else {
this.mDataset = data;
}
}

dalmif
سه شنبه 25 آذر 1393, 19:17 عصر
منم دقیقا چنین سوالی رو دارم

hosseinaryai
چهارشنبه 26 آذر 1393, 09:07 صبح
ممنونم بابت پیگیریت دوست خوبم ..
یه چیزایی فهمیدم اما با این بازم اداپترو می ذارم شاید بد متوجه شده باشم :
این List_details منه :


public class List_details {

private String namkol,datkol;
private LinearLayout linkol;

public String getNamKol()
{
return namkol;
}
public void setNamKol(String namkol)
{
this.namkol = namkol;
}


public String getEmtKol()
{
return datkol;
}
public void setEmtKol(String datkol)
{
this.datkol = datkol;
}


public LinearLayout getLintKol()
{
return linkol;
}
public void setLinKol(LinearLayout linkol)
{
this.linkol = linkol;
}

}


و اینم List_adapt :


public class List_adapt extends BaseAdapter{

private static ArrayList<List_details> itemDetailsrrayList;
LayoutInflater layoutInflator;
Context context;

public List_adapt(ArrayList<List_details> result , Context c) {
itemDetailsrrayList = result;
context = c;
}

public int getCount() {
return itemDetailsrrayList .size();
}

public Object getItem(int arg0) {
return itemDetailsrrayList .get(arg0);
}

public long getItemId(int position) {
return position;
}

@SuppressLint("ViewHolder")
public View getView(final int position, View convertView, ViewGroup parent) {
layoutInflator =
(LayoutInflater)context.getSystemService(Context.L AYOUT_INFLATER_SERVICE);
View row = layoutInflator.inflate(R.layout.list_agahi, parent,false);

LinearLayout linkol = (LinearLayout) row.findViewById(R.id.lin_list);
TextView txt_nam = (TextView) row.findViewById(R.id.txt_nam_list);
TextView txt_dat = (TextView) row.findViewById(R.id.txt_dat_list);

txt_nam.setText(itemDetailsrrayList.get(position). getNamKol());
txt_dat.setText(itemDetailsrrayList.get(position). getEmtKol());

linkol.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {

}
});

return (row);
}
}

Nevercom
چهارشنبه 26 آذر 1393, 15:02 عصر
شما آداپتور رو بر اساس توضیحات من تغییر ندادید.

اول اینکه دیتا رو از Constructor کلاس آداپتور خارج کنید، یعنی کد زیر تبدیل بشه به کد بعدیش:

public List_adapt(ArrayList<List_details> result , Context c) {
itemDetailsrrayList = result;
context = c;
}

به:

public List_adapt(Context c) {


context = c;
}


در مرحله ی بعد متدی برای اضافه کردن Data به کلاس آداپتور اضافه کنید:

public void setData(List<List_details> data, boolean addData) {
if (addData && this.itemDetailsrrayList != null) {
this.itemDetailsrrayList.addAll(data);
} else {
this.itemDetailsrrayList = data;
}
}


حالا آداپتور شما پس از ساخته شدن میتونه در هر مرحله داده ها رو دریافت کنه و نمایش بده، و میتونید داده های جدید رو با این متد به داده های قبلی اضافه کنید (کافیه پارامتر دوم متد setData برابر با true باشه)

hosseinaryai
چهارشنبه 26 آذر 1393, 17:50 عصر
یسسسسسسسسسسسس .. درست شد .. دمت گرم:بوس::بامزه:

dalmif
چهارشنبه 26 آذر 1393, 19:16 عصر
hosseinaryai (http://barnamenevis.org/member.php?268244-hosseinaryai) میشه کدی رو که داری برای من هم قرار بدی؟

hosseinaryai
چهارشنبه 26 آذر 1393, 20:45 عصر
خب نیگا .. adapter این شکلی میشه :


public class List_adapt extends BaseAdapter{

private static ArrayList<List_details> itemDetailsrrayList;
LayoutInflater layoutInflator;
Context context;

/* public List_adapt(ArrayList<List_details> result , Context c) {
itemDetailsrrayList = result;
context = c;
}*/

public List_adapt(Context c) {

context = c;
}

public int getCount() {
return itemDetailsrrayList .size();
}

public Object getItem(int arg0) {
return itemDetailsrrayList .get(arg0);
}

public long getItemId(int position) {
return position;
}

public void setData(ArrayList<List_details> data, boolean addData) {
if (addData && itemDetailsrrayList != null) {
itemDetailsrrayList.addAll(data);
} else {
itemDetailsrrayList = data;
}
}

@SuppressLint("ViewHolder")
public View getView(final int position, View convertView, ViewGroup parent) {
layoutInflator =
(LayoutInflater)context.getSystemService(Context.L AYOUT_INFLATER_SERVICE);
View row = layoutInflator.inflate(R.layout.list_agahi, parent,false);

LinearLayout linkol = (LinearLayout) row.findViewById(R.id.lin_list);
TextView txt_nam = (TextView) row.findViewById(R.id.txt_nam_list);
TextView txt_dat = (TextView) row.findViewById(R.id.txt_dat_list);

txt_nam.setText(itemDetailsrrayList.get(position). getNamKol());
txt_dat.setText(itemDetailsrrayList.get(position). getEmtKol());

linkol.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {

}
});

return (row);
}


از اون طرف توی اکتیویتی این چهار تا رو عمومی تعریف کردم :

ArrayList<List_details> result1;
List_adapt adapter ;
private static int MAX_ITEMS_PER_PAGE = 10;
private static boolean loadingMore = true;


بعد توی متد onCreate برای بار اول به این صورت پرش کردم :


result1 = GetSearchResults();
adapter = new List_adapt(Page_shakhsi.this);
adapter.setData(result1,loadingMore);
list_sh.setAdapter(adapter);


و متد GetSearchResults هم اینجوری تغییر کرد :


private static ArrayList<List_details> GetSearchResults() {
ArrayList<List_details> results = new ArrayList<List_details>();

if(shakhsi_dat.length>MAX_ITEMS_PER_PAGE){
for(int i = 0; i <= MAX_ITEMS_PER_PAGE; i++)
{

list_shakhsi = new List_details();
list_shakhsi.setNamKol(shakhsi_titl[i]);
list_shakhsi.setEmtKol(shakhsi_dat[i]);

results.add(list_shakhsi);

}
loadingMore = false;
MAX_ITEMS_PER_PAGE = MAX_ITEMS_PER_PAGE + 10 ;
}else{

loadingMore = true;
list_sh.setOnScrollListener(null);
list_sh.removeFooterView(footer);
}

return results;
}


و در آخر onScroll رو اینجوری نوشتم :


public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;

if((lastInScreen == totalItemCount) && !(loadingMore)){

adapter.setData(GetSearchResults(),loadingMore);
adapter.notifyDataSetChanged();

}
}

87375009
شنبه 30 خرداد 1394, 19:35 عصر
سلام
من به همین روش توی لیست ویو اطلاعات رو قرار میدم و وقتی که به آخر لیست میرسه 10 آیتم بعد رو لود میکنه
مشکل اینجا پیش میاد که اگه با سرعت زیاد اسکرول کنیم اطلاعات تکراری لود میشه ولوپ میخوره
کسی به این مشکل برخورده
لطفا راهنمایی کنید

tux-world
یک شنبه 31 خرداد 1394, 00:37 صبح
اطلاعات تکراری باشه حتما مشکل از اداپتورتون هستش. نمیدونم چطوری کد زدید ولی اشکال از لود شدن نیست

michael.0855
یک شنبه 08 آذر 1394, 22:59 عصر
با سلام
دوستان من چند روزه دارم درمورد این قضیه تحقیق میکنم اما هنوز موفق نشدم ازش استفاده کنم
اگه امکانش هست اول نحوه عملکرد endless scroll listview رو بگید و بعد اگه امکانش هست نمونه کد هاشو بدید
منم مثل دوستمون از لیست سفارشی استفاده میکنم
ممنون از همگی:چشمک::چشمک::چشمک:

mohsen1993
سه شنبه 12 مرداد 1395, 15:44 عصر
سلام دوستان
پیرو بحث مطرح شده توسط دوستمون بنده هم چنین مشکلی دارم
کد های من به صورت زیر هست:

}public class list_story extends ListActivity
private database db;
private String[] Name;
private String[] Fav;
private String[] Tasvir;
private String[] Scientific;
private String[] English;
public ListView lv;
private String sea;
boolean loadingMore=true;
Context c;
ArrayAdapter<String> adapter;





@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.list_story);
lv=getListView();
c=getBaseContext();

db = new database(this);
Bundle ex = getIntent().getExtras();
sea = ex.getString("sea");

refresh();

lv.setAdapter(new AA());


@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent i = new Intent(list_story.this,Main_matn.class);
i.putExtra("sea", sea);
i.putExtra("name", Name[position]);
i.putExtra("fav", Fav[position]);
i.putExtra("tasvir", Tasvir[position]);
i.putExtra("scientific", Scientific[position]);
i.putExtra("english", English[position]);
startActivity(i);

}



class AA extends ArrayAdapter<String>{



public AA(){
super(list_story.this,R.layout.row_list,Name);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {

LayoutInflater in = getLayoutInflater();
View row = in.inflate(R.layout.row_list, parent,false);

TextView txt = (TextView) row.findViewById(R.id.show_season_name);
txt.setText(Name[position]);
return (row);
}
}

private void refresh(){
db.open();
int s =db.Story_count("content", sea);
Name = new String[s];
Fav=new String[s];
Tasvir=new String[s];
Scientific=new String[s];
English=new String[s];


for (int i = 0; i < s; i++) {
Name[i]=db.Story_display(i, sea, "content", 1);
Fav[i]=db.Story_display(i, sea, "content", 4);
Tasvir[i]=db.Story_display(i, sea, "content", 5);
Scientific[i]=db.Story_display(i, sea, "content", 6);
English[i]=db.Story_display(i, sea, "content", 7);

}
db.close();
}



مشکل من به کارگیری متدهای onscroll و نحوه ی برگرداندن آرایه Name و پاس دادنش به این متد هست.
خوشحال میشم از راهنمایی هاتون استفاده کنم.