I am trying to slide image in viewPager, images sliding well automatically while I am using images from drawable folder. But while I am tying to show images from server to be slided from server image url its showing error something like this:
The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged!
I have tried to solve this problem by googling but I could not solve that. I need help. My code is below:
activity work:
String imageListQuery=null;
try {
imageListQuery=URLEncoder.encode("getChatRooms", "UTF-8") + "=" + URLEncoder.encode("getChatRooms", "UTF-8");
backgroundTask=new AsyncTaskClass(context_NavigationActivity, new AsyncTaskResult() {
#Override
public void AsyncTaskResult(String result) throws JSONException {
if(result!=null){
pageViewerAdapter.notifyDataSetChanged();
}
JSONObject js = new JSONObject(result);
// Log.v("ResDFrJ",js.toString());
JSONArray arr = js.getJSONArray("result");
for (int i = 0; i < arr.length(); i++) {
JSONObject tmpOb = new JSONObject(arr.optString(i));
UsersListShowClass tmpClass = new UsersListShowClass();
tmpClass.setProPicUrl_users(InfoSetClass.getBaseUrl()+tmpOb.getString("profile_pic_id"));
imageList.add(i,tmpClass);
}
}
});
backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"POST","mobileApi/chatRooms",imageListQuery);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
viewPager=(ViewPagerCustomDuration)findViewById(R.id.pageViewerId);
viewPager.setScrollDurationFactor(15);
pageViewerAdapter=new PageViewerAdapter(context_NavigationActivity,imageList);
NUM_PAGES=pageViewerAdapter.getCount();
viewPager.setAdapter(pageViewerAdapter);
pageViewerAdapter.notifyDataSetChanged();
final Handler handler = new Handler();
final Runnable update = new Runnable() {
public void run() {
if (currentPage == NUM_PAGES - 1) {
currentPage = 0;
}
viewPager.setCurrentItem(currentPage++, true);
}
};
new Timer().schedule(new TimerTask() {
#Override
public void run() {
handler.post(update);
}
}, 100, 5000);
adapter:
public class PageViewerAdapter extends PagerAdapter {
private Context context;
private ArrayList<UsersListShowClass> imageList;
UsersListShowClass usersListShowClass;
public PageViewerAdapter(Context context,ArrayList<UsersListShowClass> imageList){
this.context=context;
this.imageList=imageList;
}
#Override
public int getCount() {
if(imageList != null){
return imageList.size();
}
return 0;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view==(LinearLayout)object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater layoutInflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=layoutInflater.inflate(R.layout.page_viewer_adapter_layout,container,false);
ImageView imageView=(ImageView)view.findViewById(R.id.videoViewId);
usersListShowClass=imageList.get(position);
Picasso.with(context).load(usersListShowClass.getProPicUrl_users()).error(R.drawable.ic_circle_24dp).
placeholder(R.drawable.ic_circle_24dp).into(imageView);
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
#Override
public int getItemPosition(Object object) {
return PageViewerAdapter.POSITION_NONE;
}
}
i know its already solved almost similar error in stackoverflow, but in my case maybe a little different. please need help.
Try to add:
pageViewerAdapter.notifyDataSetChanged();
after:
imageList.add(i,tmpClass);
Related
How to make it automatically view pager in few seconds?
I have tried several ways but still failed when viewpager changes
Error message is "Attempt to invoke interface method 'int java.util.List.size()' on a null object reference"
private Handler handler;
private int delay = 5000; //milliseconds
private int page = 0;
private HomeSliderPagerAdapter myAdapter;
Runnable runnable = new Runnable() {
public void run() {
if (myAdapter.getCount() == page) {
page = 0;
} else {
page++;
}
viewPager.setCurrentItem(page, true);
handler.postDelayed(this, delay);
}
};
on ActivityCreated
handler = new Handler();
viewPager = (ViewPager) getActivity().findViewById(R.id.vPager);
sliderImg = new ArrayList<>();
volleyObjectResult = new VolleyObjectResult() {
#Override
public void resSuccess(String requestType, JSONObject response) {
try {
//String images = response.getString("images");
JSONArray jsonArray = response.getJSONArray("banner");
for (int i=0; i<jsonArray.length(); i++) {
SliderUtil sliderUtil = new SliderUtil();
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
sliderUtil.setSliderImgUrl(jsonObject.getString("IMAGES"));
Log.e(TAG, "Test -> " + jsonObject.getString("IMAGES"));
}catch(Exception e){
e.printStackTrace();
}
sliderImg.add(sliderUtil);
}
HomeSliderPagerAdapter hspa = new HomeSliderPagerAdapter(sliderImg, getActivity());
hspa.notifyDataSetChanged();
viewPager.setAdapter(hspa);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
page = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void resError(String requestType, VolleyError error) {
Toast.makeText(getActivity(), "Network connection problem", Toast.LENGTH_LONG).show();
}
};
volleyObjectService = new VolleyObjectService(volleyObjectResult, getActivity());
volleyObjectService.postJsonObject("GETCALL", requestUrl, data);
}
Result:
when the image changes it will force close with an error message "Attempt to invoke interface method 'int java.util.List.size()' on a null object reference"
Use View Pager custom adapter
public class SliderPagerAdapter extends PagerAdapter {
private LayoutInflater layoutInflater;
Activity activity;
List<ImageSliderModel> imageSliderModels;
public SliderPagerAdapter(Activity activity, List<ImageSliderModel> imageSliderModels) {
this.activity = activity;
this.imageSliderModels = imageSliderModels;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.layout_slider, container, false);
ImageView im_slider = (ImageView) view.findViewById(R.id.im_slider);
String url = imageSliderModels.get(position).getImage();
Glide.with(activity).load(imageSliderModels.get(position).getImage()).into(im_slider);
container.addView(view);
return view;
}
#Override
public int getCount() {
return imageSliderModels.size();
}
#Override
public boolean isViewFromObject(View view, Object obj) {
return view == obj;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
View view = (View) object;
container.removeView(view);
}
And in Activity call view pager and adapter
mvViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i1) {
}
#Override
public void onPageSelected(int i) {
addBottomDots(i, ll_dots);
page = i;
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
h.postDelayed(new Runnable() {
#Override
public void run() {
try {
if (sliderPagerAdapter.getCount() == page) {
page = 0;
} else {
page++;
}
}catch (Exception ignored)
{
}
mvViewPager.setCurrentItem(page);
h.postDelayed(this, 4000);
}
}, 1000);
And pass list to Custom adapter like this.
sliderPagerAdapter = new SliderPagerAdapter((Activity) HomeScreen.this, imageSliderModels);
mvViewPager.setAdapter(sliderPagerAdapter);
sliderPagerAdapter.notifyDataSetChanged();
private void setTimer()
{
CountDownTimer countDownTimer = new CountDownTimer(5000,2000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
if(viewPager.getCurrentItem() < arrayList.size() - 1)
{
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
}
else {
viewPager.setCurrentItem(0);
}
countDownTimer.start();
}
};
countDownTimer.start();
}
In my project, there is need of searching data from server using keyword. After search, i am displaying results using RecyclerView . While searching fast, the data in RecyclerView is duplicating. If searching slowly, it's working fine. Any suggestions are appreciated. Thank you.
The below code for making server call:
private void callSearchUserApi(final String searchText, int currentPage, boolean clearData) {
isApiCallInProcess = true;
String URL = "userinfo/api/v1/user-search/" + "?page=" + currentPage;
if (!Connectivity.isConnected(activity)) {
Common.snackBarNoConnection(activity, activity.getString(R.string.no_conection));
//setOnProgressbarVisibility(View.GONE);
return;
}
if (clearData) {
globalSearchUsersModelList.clear();
//BS globalSearchUserResultsAdapter.notifyDataSetChanged();
}
ApiInterface apiCall = ApiClient.getApiService(activity);
final Call<SearchUsersModel> globalUserSearchApiCall = apiCall.searchUser(
URL,
searchText);
globalUserSearchApiCall.enqueue(new Callback<SearchUsersModel>() {
#Override
public void onResponse(Call<SearchUsersModel> call, Response<SearchUsersModel> response) {
if (response.isSuccessful() && response.body().getStatus().equalsIgnoreCase(Common.SUCCESS_RESPONSE)) {
//BS globalSearchUsersModelList.addAll(response.body().getData().getData());
for (int i = 0; i < response.body().getData().getData().size(); i++) {
SearchUsersModel.DataBeanX.DataBean dataBean = new SearchUsersModel.DataBeanX.DataBean();
dataBean.setDesignation(response.body().getData().getData().get(i).getDesignation());
dataBean.setFull_name(response.body().getData().getData().get(i).getFull_name());
dataBean.setGender(response.body().getData().getData().get(i).getGender());
dataBean.setId(response.body().getData().getData().get(i).getId());
dataBean.setPlace(response.body().getData().getData().get(i).getPlace());
dataBean.setProfile_pic(response.body().getData().getData().get(i).getProfile_pic());
globalSearchUsersModelList.add(dataBean);
/*BS if (!globalSearchUsersModelList.contains(response.body().getData().getData().get(i)))
globalSearchUsersModelList.add(response.body().getData().getData().get(i));*/
}
CURRENT_PAGE = response.body().getData().getPage();
isLoading = false;
if (response.body().getData().isNext() == false)
isLastPage = true;
else
isLastPage = false;
if (globalSearchUsersModelList.size() == 0) {
rv_GlobalsearchList.setVisibility(View.GONE);
rl_placeholderGSPeople.setVisibility(View.VISIBLE);
tv_placeholderGSPeople.setText(activity.getString(R.string.no_search_found) + " " + searchText);
} else {
rv_GlobalsearchList.setVisibility(View.VISIBLE);
rl_placeholderGSPeople.setVisibility(View.GONE);
}
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
globalSearchUserResultsAdapter.notifyDataSetChanged();
}
});
}
if (searchTextsList.size() > 0) {
String sText = searchTextsList.get(0);
searchTextsList.remove(0);
callSearchUserApi(sText, FIRST_PAGE, true);
} else
isApiCallInProcess = false;
}
#Override
public void onFailure(Call<SearchUsersModel> call, Throwable t) {
isApiCallInProcess = false;
}
});
}
This is my Adapter.
public class GlobalSearchUserResultsAdapter extends RecyclerView.Adapter<GlobalSearchUserResultsAdapter.SearchViewHolder> {
private Context context;
private List<SearchUsersModel.DataBeanX.DataBean> searchUserList;
public GlobalSearchUserResultsAdapter(Context context, List<SearchUsersModel.DataBeanX.DataBean> searchUserList){
this.context = context;
this.searchUserList = searchUserList;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public SearchViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.v("Search", "Adapter Activity : "+context);
View view = LayoutInflater.from(context).inflate(R.layout.global_search_row, parent, false);
return new GlobalSearchUserResultsAdapter.SearchViewHolder(view);
}
#Override
public void onBindViewHolder(GlobalSearchUserResultsAdapter.SearchViewHolder holder, int position) {
if ( searchUserList.get(position).getGender().equals("M")) {
holder.iv_userImage.setBackgroundResource(R.drawable.white_border_with_circle_appblue);
Common.setGlideImage((GlobalSearchActivity)context,
holder.iv_userImage,
/*searchUsersModel*/searchUserList.get(position).getProfile_pic(),
R.drawable.male,
true);
} else if (searchUserList.get(position).getGender().equals("F")) {
holder.iv_userImage.setBackgroundResource(R.drawable.white_border_with_circle_pink);
Common.setGlideImage((GlobalSearchActivity)context,
holder.iv_userImage,
searchUserList.get(position).getProfile_pic(),
R.drawable.female,
true);
} else {
Common.setGlideImage((GlobalSearchActivity)context,
holder.iv_userImage,
searchUserList.get(position).getProfile_pic(),
R.drawable.deafult_profilepic,
true);
}
holder.tv_userName.setText(searchUserList.get(position).getFull_name());
holder.tv_userName.setTypeface(Common
.getFontTypeface(context, GlobalConstants.FONT_AVENIR_MEDIUM));
holder.tv_place.setText(searchUserList.get(position).getPlace());
holder.tv_place.setTypeface(Common
.getFontTypeface(context, GlobalConstants.FONT_AVENIR_MEDIUM));
holder.designation.setText(searchUserList.get(position).getDesignation());
}
#Override
public int getItemCount() {
return searchUserList.size();
}
public class SearchViewHolder extends RecyclerView.ViewHolder{
private ImageView iv_userImage;
private TextView tv_userName;
private TextView tv_place;
private TextView designation;
public SearchViewHolder(View itemView) {
super(itemView);
this.iv_userImage = (ImageView) itemView.findViewById(R.id.imageSearch);
this.tv_userName = (TextView) itemView.findViewById(R.id.nameSearch);
tv_userName.setTypeface(Common.getFontTypeface(context,
GlobalConstants.FONT_AVENIR_MEDIUM));
this.designation = (TextView) itemView.findViewById(R.id.designation);
designation.setTypeface(Common.getFontTypeface(context,
GlobalConstants.FONT_AVENIR_MEDIUM));
this.tv_place = (TextView) itemView.findViewById(R.id.placeSearch);
tv_place.setTypeface(Common.getFontTypeface(context,
GlobalConstants.FONT_AVENIR_LIGHT));
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
context.startActivity(new Intent(context, ProfileActivity.class)//ThirdParty
.putExtra(GlobalConstants.KEY_THIRD_PARTY_ID, searchUserList.get(getAdapterPosition()).getId()));
}
});
}
}
}
You just had to clear the globalSearchUsersModelList list just before for loop, because API call is asynchronous.
globalSearchUsersModelList.clear();// Important one
for (int i = 0; i < response.body().getData().getData().size(); i++) {
// do your stuff
}
I think the issue come from your getItemId implementation. The way you implement it, the recycler view will identify an item according to its position in the list.
If you change this and use unique identification for instance searchUserList.get(position).id (if your User object has an unique ID) the problem should be fixed
You can also add in your activity adapter.setHasStableIds(true)
I am developing an android app where I use viewpager to show some images from a rest api. These Api has lots of images in json format. I only want to show the the first 8 or 10 images into viewpager. But I am not getting the correct way to loop throug the images. Here is my code for view pager.
private static ViewPager viewPager;
private static int currentPage = 0;
private List<NewsModel> imageList=new ArrayList<>( );
private ViewPagerAdapter adapter;
private NewsController mController;
private Timer swipeTimer;
private Handler handler;
private Runnable Update;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.option_main_fragment, container, false);
viewPager = view.findViewById(R.id.pager);
adapter=new ViewPagerAdapter( this.getActivity(),imageList );
CircleIndicator indicator = (CircleIndicator) view.findViewById(R.id.indicator);
viewPager.setAdapter(adapter);
indicator.setViewPager(viewPager);
adapter.registerDataSetObserver(indicator.getDataSetObserver());
mController = new NewsController(this);
mController.startFetching();
return view;
}
#Override
public void onResume() {
// Auto start of viewpager
handler = new Handler();
Update= new Runnable() {
public void run() {
if (currentPage == imageList.size()) {
currentPage = 0;
}
viewPager.setCurrentItem(currentPage++, true);
System.out.println(viewPager.getCurrentItem());
}
};
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
},2000,5000);
super.onResume();
}
#Override
public void onPause() {
swipeTimer.cancel();
super.onPause();
}
Edited Code This is the code for fetching json data
public class NewsController {
private static final String TAG = NewsController.class.getSimpleName();
private UserCallbackListener mListener;
private NewsRestApiManager mApiManager;
private AppImage appImages;
Realm news_realm;
ArrayList<String> title_list = new ArrayList<>();
GlobalClass globalClass = new GlobalClass();
public NewsController(UserCallbackListener listener) {
mListener = listener;
mApiManager = new NewsRestApiManager();
}
public void startFetching(){
news_realm = Realm.getDefaultInstance();
mApiManager.getNewsApi().getNews(new Callback<String>() {
#Override
public void success(String s, Response response) {
Log.d(TAG, "JSON :: " + s);
try {
JSONArray array = new JSONArray(s);
for(int i = 0; i < array.length(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
NewsModel news = new NewsModel();
news.setTitle( jsonObject.optString( "title") );
news.setBody( jsonObject.optString( "body" ) );
news.setUpdatedAt( jsonObject.getString( "updated_at" ) );
ArrayList<AppImage> list = new ArrayList();
JSONArray imageArray =jsonObject.getJSONArray("appImages");
if (imageArray.length() > 1) {
for(int j=0; j<imageArray.length();j++){
appImages = new AppImage();
try {
appImages.setSrc( new JSONArray( s ).getJSONObject( i ).getJSONArray( "appImages" ).getJSONObject( j ).optString( "src" ) );
}catch (JSONException e){
e.printStackTrace();
}
list.add(appImages);
}
}
news.setAppImages( list );
TeaserImageSmall coverImage=new TeaserImageSmall();
try {
coverImage.setSrc( jsonObject.getJSONObject("teaserImageSmall").optString("src"));
news.setTeaserImageSmall(coverImage);
} catch (JSONException e) {
Log.d(TAG, "News image could not be loaded for: " + news.getTitle());
}
mListener.onFetchProgressNews(news);
}
} catch (JSONException e) {
mListener.onFetchFailed();
}
mListener.onFetchComplete();
}
#Override
public void failure(RetrofitError error) {
Log.d(TAG, "Error :: " + error.getMessage());
mListener.onFetchComplete();
}
});
}
public interface UserCallbackListener{
void onFetchProgressNews(NewsModel news);
void onFetchComplete();
void onFetchFailed();
}
}
Adapter Class
public class ViewPagerAdapter extends PagerAdapter{
private List<NewsModel> imageList;
private LayoutInflater layoutInflater;
private Context context;
public ViewPagerAdapter(Context context, List<NewsModel> imageList) {
this.context = context;
this.imageList=imageList;
}
#Override
public int getCount() {
return imageList.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
layoutInflater=(LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
View itemView = layoutInflater.inflate(R.layout.sliding_img_layout, view, false);
final NewsModel imageFromNews=imageList.get( position );
ImageView myImage = itemView.findViewById(R.id.sliding_image);
Picasso.with(itemView.getContext()).load(imageFromNews.getTeaserImageSmall().getSrc()).into( myImage );
view.addView(itemView, 0);
myImage.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i=new Intent(context,DetailNews.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("src",imageFromNews.getTeaserImageSmall().getSrc());
i.putExtra("title",imageFromNews.getTitle());
i.putExtra("body",imageFromNews.getBody());
context.startActivity(i);
}
} );
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
I guess you can change the code as below
ArrayList<AppImage> list = new ArrayList();
JSONArray imageArray =jsonObject.getJSONArray("appImages");
if (imageArray.length() > 1) {
for(int j=0; j<imageArray.length() && j < 8;j++) { // Added condition j < 8
appImages = new AppImage();
try {
appImages.setSrc( new JSONArray( s ).getJSONObject( i ).getJSONArray( "appImages" ).getJSONObject( j ).optString( "src" ) );
}catch (JSONException e){
e.printStackTrace();
}
list.add(appImages);
}
}
news.setAppImages( list );
there are other ways to do this as well
you can fix viewpager item count
#Override
public int getCount() {
return imageList.size() <= 8? imageList.size():8;
}
Please excuse my English. I have an activity consists of two fragments with viewpager. And every fragment has a listview.
I am using this data in many locations, so i have created this as static.
class DataHandler {
static ArrayList<MenuHolder> listOfItemsFromJson = new ArrayList<MenuHolder>();
public static ArrayList<MenuHolder> getListOfItemsFromJson() {
return listOfItemsFromJson;
}
public static void addData(MenuHolder holder) {
listOfItemsFromJson.add(holder);
}
public static MenuHolder getData(int position) {
return listOfItemsFromJson.get(position);
}
public static void modifyData(MenuHolder holder, int position) {
listOfItemsFromJson.set(position, holder);
}
public static int size() {
return listOfItemsFromJson.size();
}
}
Here, My fragment code. In onCreateView(), I am clearing the previous data &
adding the fresh data.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_combo, container, false);
mlistView = (ListView) view.findViewById(R.id.mListView);
//here I am clearing the previous data and loading new data
for (int i = 0; i < DataHandler.size(); i++) {
if (DataHandler.getData(i).isCombo()) {
DataHandler.removeData(i);
}
}
for (int i = 0; i < 3; i++) {
MenuHolder mMenuHolder = new MenuHolder();
mMenuHolder.setItemname(itemNames[i]);
mMenuHolder.setImageName("#mipmap/ic_launcher");
mMenuHolder.setItemCount("0");
mMenuHolder.setItemprice("500");
mMenuHolder.setUserSeleted(false);
mMenuHolder.setCombo(true);
DataHandler.addData(mMenuHolder);
}
index.clear();
for (int i = 0; i < DataHandler.size(); i++) {
if (DataHandler.getListOfItemsFromJson().get(i).isCombo()) {
index.add(i);
}
}
mCombosAdapter = new ComboMenuAdapter(getActivity(), index);
mlistView.setVisibility(View.VISIBLE);
mlistView.setAdapter(mCombosAdapter);
return view;
}
Here I am getting the wrong values. DataHandler.size() is wrong.
for (int i = 0; i < DataHandler.size(); i++) {
if (DataHandler.getListOfItemsFromJson().get(i).isCombo()) {
index.add(i);
}
}
Here, I am navigating to another activity and having some modifications in dataHandler class & after coming back the list size is wrong & list size is increasing.
I think your DataHandler should as a singleton;
class DataHandler {
private static DataHandler mInstance = null;
ArrayList<MenuHolder> listOfItemsFromJson;
public DataHandler getInstance() {
if(null == mInstance) {
mInstance = new DataHandler();
}
}
public DataHandler() {
listOfItemsFromJson = new ArrayList<MenuHolder>();
}
public ArrayList<MenuHolder> getListOfItemsFromJson() {
return listOfItemsFromJson;
}
public void addData(MenuHolder holder) {
listOfItemsFromJson.add(holder);
}
public MenuHolder getData(int position) {
return listOfItemsFromJson.get(position);
}
public void modifyData(MenuHolder holder, int position) {
listOfItemsFromJson.set(position, holder);
}
public int size() {
return listOfItemsFromJson.size();
}
}
You can user it like : DataHandler.getInstance().size();
But i think you set dataHandler as static is ugly...
you can create a adapter replace DataHandler, then your all listview can use this adapter.
My fragment activity used this adapter to display all the result in a listview.
The page will have a title tab and each tab will have the list result. Now the list result I read from internal storage and each time I swipe to next page it will have slight lag or delay, so I am thinking implementing ASYNCTask inside this pageradapter so the experience will be better but I have no idea where to implement. Could you guys point me out??
public class ViewPagerAdapter extends PagerAdapter
{
public ViewPagerAdapter( Context context )
{
//This is where i get my title
for (HashMap<String, String> channels : allchannel){
String title = channels.get(KEY_TITLE);
titles[acc] = title;
acc++;
}
scrollPosition = new int[titles.length];
for ( int i = 0; i < titles.length; i++ )
{
scrollPosition[i] = 0;
}
}
#Override
public String getPageTitle( int position )
{
return titles[position];
}
#Override
public int getCount()
{
return titles.length;
}
#Override
public Object instantiateItem( View pager, final int position )
{
String filename = null;
ListView v = new ListView( context );
final ArrayList<HashMap<String, String>> items = new ArrayList<HashMap<String, String>>();
DatabaseHandler db = new DatabaseHandler(context);
filename = openFile("PAGE1"); //OpenFile function is read file from internal storage
switch(position){
case 0:
filename = openFile("PAGE1");
break;
case 1:
filename = openFile("PAGE2");
break;
case 2:
filename = openFile("PAGE3");
break;
}
try{
//Use json to read internal storage file(Page1/Page2) and display all the result on the list
}
}catch(Exception e){
}
ListAdapter listadapter=new ListAdapter(context, items);
v.setAdapter( listadapter );
((ViewPager)pager ).addView( v, 0 );
return v;
}
#Override
public void destroyItem( View pager, int position, Object view )
{
( (ViewPager) pager ).removeView( (ListView) view );
}
#Override
public boolean isViewFromObject( View view, Object object )
{
return view.equals( object );
}
#Override
public void finishUpdate( View view )
{
}
#Override
public void restoreState( Parcelable p, ClassLoader c )
{
if ( p instanceof ScrollState )
{
scrollPosition = ( (ScrollState) p ).getScrollPos();
}
}
#Override
public Parcelable saveState()
{
return new ScrollState( scrollPosition );
}
#Override
public void startUpdate( View view )
{
}
}
I would suggest doing it like this
#Override
public Object instantiateItem( View pager, final int position )
{
//Some other work related to instantiation of item
AsyncTask<Uri, Void, Bitmap> mLoadTask = new AsyncTask<Uri, Void, Bitmap>() {
//async task for loading images in background
#Override
protected void onPostExecute(Bitmap result) {
pageview[position].setImageBitmap(result);
//post in ui thread
//this way you have a reference object for each item(using position)
//and hence you can start several tasks at the same time
}
#Override
protected Bitmap doInBackground(Uri... params) {
Bitmap bitmap=getBitmap(params[0]);
//here getBitmap returns the bitmap using uri arguement
return bitmap;
}
};
mLoadTask.execute(Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + image_id));
}
This way each item has its own thread and you need not worry no matter how many items get loaded.
EDIT One more thing, you can return pageview[position] from this method right after the AsyncTask code, this way the View will appear blank(smooth scrolling achieved) until AsyncTask completes the background work. But it would still be able to set the Bitmap to the correct View because it has reference inside onPostExecute
I'm doing it in constructor, and it's working fine. Example:
public MyAdapter(Context context) {
this.context = context;
try {
whatIneed = new DoSomeAsyncStuff(this.context).execute().get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}