Am using a ViewPager with adapter to show some pictures (as a gallery) and I need to return the name of the picture when the user click above
my problem that I can not implement onclick from the adapter because I can't return the result to the calling activity, and when I implement the viewAdapter.addOnPageChangeListener I have to wait until the page is changed so if the user clicks on the first pic it well not work
here is my code:
for(int i=0;i<images.length;i++)
imagesArray.add(images[i]);
MyAdapter myAdapter = new MyAdapter(MyImagePicker.this,imagesArray);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(myAdapter);
//CircleIndicator indicator = (CircleIndicator) findViewById(R.id.indicator);
//indicator.setViewPager(mPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(mPager, true);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Toast.makeText(getApplicationContext()," pos : "+position,Toast.LENGTH_LONG).show();
// return result //
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
class MyAdapter extends PagerAdapter {
private ArrayList<Integer> images;
private LayoutInflater inflater;
private Context context;
public MyAdapter(Context context, ArrayList<Integer> images) {
this.context = context;
this.images=images;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return images.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
View myImageLayout = inflater.inflate(R.layout.slider, view, false);
final ImageView myImage = (ImageView) myImageLayout
.findViewById(R.id.image);
myImage.setImageResource(images.get(position));
myImage.setTag(position+1);
myImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context," pos : "+view.getTag(),Toast.LENGTH_LONG).show();
}
});
view.addView(myImageLayout, 0);
return myImageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
}
There are a few approaches you could take:
1) Create a callback interface. In your activity implement the interface (create a listener) and pass it into the adapter's constructor, when the user clicks on an image, pass the image name back to the activity using the callback (mlistener.onImageChosen(view.getTag()).
public interface ImageChosenListener
{
void onImageChosen(String image);
}
2) Use a broadcast from the adapter and have a broadcast receiver in your activity.
try this.
mPager.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(mPager.getCurrentItem()){
case 0: // its position 0
//somthing
break;
.
.
.
}
});
Thanks jt-gilkeson,
I think using a callBack interface is the perfect and the easiest solution :
Here is my answer :
// Create a callBack interface
public interface CallBack {
void callBack(String pos);
}
// The activity hosting my picture gallery
public class MyImagePicker extends Activity implements CallBack {
private static ViewPager mPager;
private static final Integer[] images= {R.drawable.p1,R.drawable.p2,R.drawable.p3,R.drawable.p4};
private ArrayList<Integer> imagesArray = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.galery_image_chooser);
init();
}
private void init() {
for(int i=0;i<images.length;i++)
imagesArray.add(images[i]);
MyAdapter myAdapter = new MyAdapter(MyImagePicker.this,imagesArray,this);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(myAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(mPager, true);
}
// Implement the call back function
public void callBack(String pos){
//return back result
Intent intent=new Intent();
intent.putExtra("imgName",pos);
setResult(2,intent);
finish();//finishing activity
}
}
Related
public class IMResponseActivity extendsAppCompatActivity implements
ViewPager.OnClickListener {
private static ViewPager viewPager_response;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.activity_imresponse);
setUI();
setViewPager();
} catch (Exception e) {
e.printStackTrace();
}
}
setViewPager() {
for (int i = 0; i < IMAGES.length; i++)
ImagesArray.add(IMAGES[i]);
viewPager_response = (ViewPager) findViewById(R.id.pager_response);
CircleIndicator indicator = (CircleIndicator) findViewById(R.id.indicator);
viewPager_response.setAdapter(new CommonSlideImageAdapter1(IMResponseActivity.this, ImagesArray));
}
public void onClick(View v) {
switch (v.getId()) {
/* case R.id.pager_response:
fragment = new ItemDetailFragment();
//Fragment fragment = new SingleProductFragment();
//Fragment fragment = new ProfileFragment();
// toolbar.setVisibility(View.GONE);
container.setVisibility(View.VISIBLE);
imresponse_layout.setVisibility(View.INVISIBLE);
ft.add(R.id.container_response_details, fragment);
ft.addToBackStack(null);
ft.commit();
break;*/
}
}
// here is my Adapter Code
public class CommonSlideImageAdapter1 extends PagerAdapter {
private ArrayList<Integer> IMAGES;
private LayoutInflater inflater;
private Context context;
public CommonSlideImageAdapter1(Context context, ArrayList<Integer> IMAGES) {
this.context = context;
this.IMAGES=IMAGES;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return IMAGES.size();
}
#Override
public Object instantiateItem(ViewGroup view, final int position) {
View imageLayout = inflater.inflate(R.layout.common_slideimage_layout1, view, false);
assert imageLayout != null;
final ImageView imageView = (ImageView) imageLayout
.findViewById(R.id.image);
imageView.setImageResource(IMAGES.get(position));
imageView.setClickable(true);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
view.addView(imageLayout, 0);
return imageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public Parcelable saveState() {
return null;
}
}
Their is no direct way to implement onItemClick listener and onClickListener in viewpager because it contains different fragments and fragments have their own listeners etc.
so the
first solution for this is implement click listener in fragment
Second solution is to implement your own click listener by extending viewpager class.
to do this there is great solution available
ViewPager OnItemClickListener
hope this will help you.
I am writing a simple view pager test app that loads a bunch of data from a website and creates pages to display them.
For the most part the displaying is pretty much all works. However, it falls apart when I load a new set of data to display. When I get a new set, it loads all the data perfectly well however, instead of starting from view 0 it starts at a random location. It could start at the end or somewhere in the middle.
I want all the data to load from page 1, like a book. If you load a new book the book should start from page 1 not a random page.
Reloading calls
I've tried using GotCampDetails() which sets the local variable in the class.
viewPager.setCurrentItem(0);
in my fragment but it doesn't work. Also called notifydatasetchanged() on my adapter, still didn't work.
What am I missing?
public class ViewPagerFragment extends Fragment implements WebReadResultsListener {
private ArrayList<HashMap<String, String>> campDetails;
CustomPagerAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.camp_viewpager, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
if (campDetails != null && ! campDetails.isEmpty()) {
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
adapter = new CustomPagerAdapter(getActivity(), campDetails, viewPager);
viewPager.setAdapter(adapter);
viewPager.setPageTransformer(true, new ZoomOutPageTransformer());
}
}
#Override
public boolean GotCampDetails(ArrayList<HashMap<String, String>> campDetails) {
this.campDetails = campDetails;
return true;
}
#Override
public boolean GotCampList(ArrayList<HashMap<String, String>> campDetails) {
return false;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getFragmentManager().putFragment(outState,"fragmentInstanceSaved",getFragmentManager().findFragmentById(R.id.content));
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Handle orientation changes here
}
}
Adapter:
public class CustomPagerAdapter extends PagerAdapter implements ColorChangeListener {
private ArrayList<HashMap<String, String>> campDetails;
private ViewGroup collection;
private Context mContext;
private boolean isRunning = false;
private ColorChangeListener colorChangeListener;
private int color= pink;
private int currentposition;
private ViewPager viewPager;
public CustomPagerAdapter(Context context, final ArrayList<HashMap<String, String>> campDetails, ViewPager viewPager) {
this.campDetails=campDetails;
this.mContext = context;
this.viewPager = viewPager;
colorChangeListener = (ColorChangeListener) mContext;
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int pos) {
currentposition = pos;
if (campDetails.get(currentposition).get("color").equals("green")) {
color = green;
} else {
color = pink;
}
ColorAppBar(color);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public Object instantiateItem(ViewGroup collection, final int position) {
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.child_item, collection, false);
if (campDetails.size() <= 0) {
Toast.makeText(mContext, "Error in getting camp details", Toast.LENGTH_SHORT).show();
return null;
}
if (campDetails.get(position).get("description").equals("RD") ) {
layout.setBackgroundColor(mContext.getResources().getColor(green));
} else {
layout.setBackgroundColor(mContext.getResources().getColor(pink));
}
collection.addView(layout);
this.collection = collection;
TextView eName = (TextView) layout.findViewById(R.id.en);
TextView nEName= (TextView) layout.findViewById(R.id.nen);
TextView textView6 = (TextView) layout.findViewById(R.id.textView6);
// ImageView nextImg = (ImageView) groupLayout.get(index).findViewById(R.id.nextImg);
eName.setText(campDetails.get(position).get("name"));
if (position+1 < campDetails.size()) {
nEName.setText(campDetails.get(position+1).get("name"));
textView6.setVisibility(View.VISIBLE);
} else {
nEName.setText("You are DONE!!");
textView6.setVisibility(View.INVISIBLE);
}
return layout;
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
#Override
public int getCount() {
return campDetails.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public CharSequence getPageTitle(int position) {
return campDetails.get(position).get("name");
}
#Override
public void ColorAppBar(int color) {
colorChangeListener.ColorAppBar(color);
}
}
I finally managed to get it done.
I had to delay the function call setCurrentItem by a few milliseconds. Race condition? I don't know why this is the case but now it works perfectly.
Here is what I added in case someone else may find it useful:
pager.postDelayed(new Runnable() {
#Override
public void run() {
pager.setCurrentItem(pos);
}
}, 100);
I'm having trouble following the details well enough to pinpoint the problem, but this guy seems to have accomplished what you're trying to do: dynamically add and remove view to viewpager
hope it helps
im trying to create an image gallery.
i have a ViewPager that each Fragment contains an image (swipable image gallery is what im trying to accomplish).
i also have a GridView that onitemclick triggers the ViewPager in the selected position showing the clicked image.
my problem is that one swipe to right and one swipe to left shows the same image as the clicked one.
ive tried setoffscreenpagelimit with no success.
this is my viewpager activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_gallery);
helper = new WeddHelper(this,"wedd.db",null,1);
pager = (ViewPager) findViewById(R.id.pager);
pager.setOnPageChangeListener(this);
Intent ing = getIntent();
curr = ing.getIntExtra("curr", 0);
byto = helper.getPhotos();
count = byto.size();
FragmentManager mg = getSupportFragmentManager();
fragments = new Vector<Fragment>();
for(int i = 0; i<count;i++){
fragments.add(Fragment.instantiate(this,GalleryFrag.class.getName()));
}
mAdapter = new FragmentAdapter(getSupportFragmentManager(), fragments, this);
pager.setAdapter(mAdapter);
pager.setOffscreenPageLimit(1);
pager.setCurrentItem(curr);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mCurrentPosition = position;
curr = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
public int getClicked(){
return curr;
}
public byte[] getPhotoToBeDisplayed(){
return byto.get(curr);
}
}
this is my custom adapter:
public class FragmentAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments=null;
private FragmentManager fragmentManager=null;
private Context context;
public FragmentAdapter(FragmentManager fragmentManager,List<Fragment> fragments, Context context) {
super(fragmentManager);
this.fragments=fragments;
this.fragmentManager=fragmentManager;
this.context = context;
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object)
{
super.setPrimaryItem(container,0,object);
}
#Override
public void notifyDataSetChanged()
{
super.notifyDataSetChanged();
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
fragmentManager.executePendingTransactions();
fragmentManager.saveFragmentInstanceState(fragments.get(position));
}
public void replaceItem(int position,Fragment fragment)
{
fragments.set(position, fragment);
this.notifyDataSetChanged();
}
}
and this is the fragment:
public class GalleryFrag extends Fragment {
WeddHelper helper;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.gallery_fragment, container, false);
ImageGallery myActivity = (ImageGallery) getActivity();
int curr = myActivity.getClicked();
byte[] photoToBeDisplayed = myActivity.getPhotoToBeDisplayed();
helper = new WeddHelper(getActivity(),"wedd.db", null, 1);
ArrayList<byte[]> imgs = helper.getPhotos();
Bitmap br = BitmapFactory.decodeByteArray(photoToBeDisplayed,0,photoToBeDisplayed.length);
Bitmap bi = BitmapFactory.decodeByteArray(imgs.get(curr),0,imgs.get(curr).length);
Toast.makeText(getActivity(), curr+"this is from frag", Toast.LENGTH_SHORT).show();
ImageView iv = (ImageView) v.findViewById(R.id.fragImage);
iv.setImageBitmap(br);
return v;
}
}
I need getCurrentView by position in a ViewPager
This my ViewPagerAdapter
public class TutorialViewPagerAdapter extends ViewPagerAdapter {
private LayoutInflater mInflater;
private View view;
private List<Integer> views;
public TutorialViewPagerAdapter(Activity act, List<Integer> views) {
super(act, null);
this.views = views;
this.mInflater = LayoutInflater.from(this.activity);
}
#Override
public void destroyItem(View container, int arg1, Object view) {
((ViewPager) container).removeView((View) view);
}
#Override
public int getCount() {
return views.size();
}
#Override
public Object instantiateItem(ViewGroup collection, int position) {
int viewId = (Integer) views.get(position);
this.view = mInflater.inflate(viewId, null);
((ViewPager) collection).addView(view);
return view;
}
}
And this is my activity
public class Tutorial extends FragmentActivity implements
ViewPager.OnPageChangeListener {
private List<Integer> views;
private TutorialViewPagerAdapter viewPagerAdapter;
private ViewPager viewPager;
private CirclePageIndicator circlePageIndicator;
private int currentViewId;
private View currentView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tutorial);
init();
}
private void init() {
views = new ArrayList<Integer>();
views.add(R.layout.tutorial_step_one);
views.add(R.layout.tutorial_step_two);
views.add(R.layout.tutorial_step_three);
views.add(R.layout.tutorial_step_four);
views.add(R.layout.tutorial_step_five);
viewPagerAdapter = new TutorialViewPagerAdapter(this, views);
viewPager = (ViewPager) findViewById(R.id.steps_view_pager);
circlePageIndicator = (CirclePageIndicator) findViewById(R.id.steps_indicator);
viewPager.setAdapter(viewPagerAdapter);
viewPager.setCurrentItem(0, false);
circlePageIndicator.setViewPager(viewPager);
circlePageIndicator.setCentered(true);
circlePageIndicator.setPadding(20, 20, 20, 20);
circlePageIndicator.notifyDataSetChanged();
circlePageIndicator.setCurrentItem(0);
viewPager.setOnPageChangeListener(this);
}
#Override
public void onPageScrollStateChanged(int state) {
int currentPosition = viewPager.getCurrentItem();
circlePageIndicator.setCurrentItem(currentPosition);
enableStep(currentPosition);
}
private void enableStep(int currentPosition) {
/*viewPagerAdapter.getItemPosition(object)
currentView = viewPager.getChildAt(viewPager.getRootView());
Log.d("DEBUG", currentView.toString() + " CURRENT VIEW");*/
}
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
}
You could add all your created views in instantiateItem to an ArrayList<View> and then make a public method for getting a view from the ArrayList with get(position). But be carefully, as soon the Activity is finished the views could be null
Instead of ViewPagerAdapter you can use FragmentPagerAdapter which will have getItem(int position) method by using which you can easily access view.
You can take a look at this post : Android Return back to same fragment after click on goto first fragment in view pager
Hope this help!!
It's moot point. What exactly You need? Current view or view by position. Imho it is different things.
Current view:
currentView = viewPager.getCurrentItem();
Or view by index (you pass wrong parameter - should be int):
currentView = viewPager.getChildAt(currentPosition);
I am using view-pager.In that I have three tabs : 1. History , 2. Main , 3. Map .
I have stopwatch into main activity.When I press the start and then after stop at that time value of the stopwatch add into the sqlite DB. And into history activity I am fetching the value of stopwatch from DB and store into the listview. It's working perfect.
But now I want the update the History activity when I swipe from the Main > History so After press the stop button,I got the last value into listview of history activity.
My question is how can I update the view on swipe the viewpager?
public class SwipeyTabsSampleActivity extends FragmentActivity {
private static final String [] TITLES = {
"HISTORY",
"MAIN",
"MAP"
};
private SwipeyTabs mTabs;
private ViewPager mViewPager;
//Handler handler=new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipeytab);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mTabs = (SwipeyTabs) findViewById(R.id.swipeytabs);
SwipeyTabsPagerAdapter adapter = new SwipeyTabsPagerAdapter(this,
getSupportFragmentManager());
mViewPager.setAdapter(adapter);
mTabs.setAdapter(adapter);
mViewPager.setOnPageChangeListener(mTabs);
mViewPager.setCurrentItem(1);
mViewPager.setOffscreenPageLimit(3);
}
private class SwipeyTabsPagerAdapter extends FragmentPagerAdapter implements
SwipeyTabsAdapter, ViewPager.OnPageChangeListener {
private final Context mContext;
ViewPager viewpager;
public SwipeyTabsPagerAdapter(Context context, FragmentManager fm, ViewPager mViewPager) {
super(fm);
this.mContext = context;
viewpager = mViewPager;
//viewpager.setAdapter(this);
viewpager.setOnPageChangeListener(this);
}
#Override
public Fragment getItem(int position) {
Fragment f = new Fragment();
switch (position) {
case 0:
f = History.newInstance(position);
break;
case 1:
f = Main.newInstance(position);
break;
case 2:
f = Map.newInstance(position);
break;
}
return f;
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
ViewPager pager = (ViewPager) container;
View view = (View) object;
pager.removeView(view);
}
public TextView getTab(final int position, SwipeyTabs root) {
TextView view = (TextView) LayoutInflater.from(mContext).inflate(
R.layout.swipey_tab_indicator, root, false);
view.setText(TITLES[position]);
view.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mViewPager.setCurrentItem(position);
}
});
return view;
}
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
#Override
public void onPageSelected(int positiion) {
// TODO Auto-generated method stub
}
}
}
Add ViewPager OnPageChangeListener:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// your code here
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
This will affect the changes from one page to another page in view pager.
OnPageChangeListener pagechangelistener =new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
Logger.logMessage("Called first");
pageAdapter.notifyDataSetChanged();
indicator.setCurrentItem(arg0);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
Logger.logMessage("Called second");
}
#Override
public void onPageScrollStateChanged(int arg0) {
Logger.logMessage("Called third");
}
};
myViewPager.setOnPageChangeListener(pagechangelistener);
Use this in your page adapter.
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Take one string and add the Getters and setters into your FragmentActivity class.
Like...
String HistoryFragment;
public String getHistoryFragment() {
return HistoryFragment;
}
public void setHistoryFragment(String historyFragment) {
HistoryFragment = historyFragment;
}
Then after we can access another fragment from our current fragment by calling findFragmentByTag(<tag of target fragment>).
For the more information check the link Communication between Fragments in ViewPager.
Have you tried implementing OnPageChanged`? You can capture when the user start swiping.
do pager.setOnPageChanged(new ....) and Eclipse will show you the methods you can override.
Then you can override onPageScrollStateChanged(int state)
onPageScrollStateChanged(int state){
if (state==OnPageChangeListener.SCROLL_STATE_DRAGGING){
// update here
}
}