First, this is my MainPageViewer:
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpager);
MyPageAdapter adapter = new MyPageAdapter();
ViewPager pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
pager.setCurrentItem(0);
The Adapter for my PageViewer is here:
public int getCount()
{
return 3;
}
public Object instantiateItem(View collection, int position)
{
LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int resId = 0;
switch(position)
{
case 0:
resId = R.layout.blogandbericht;
break;
case 1:
resId = R.layout.blogandbericht;
break;
case 2:
resId = R.layout.blogandbericht;
break;
}
View view = inflater.inflate(resId, null);
((ViewPager) collection).addView(view, 0);
return view;
}
#Override
public void destroyItem(View arg0, int arg1, Object arg2)
{
((ViewPager) arg0).removeView((View) arg2);
}
#Override
public boolean isViewFromObject(View arg0, Object arg1)
{
return arg0 == ((View) arg1);
}
#Override
public Parcelable saveState()
{
return null;
}
(Yes i know, that all layout are "bloganbericht")
And this my blogandbericht:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/masterSv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#8ad5f0">
<LinearLayout
android:id="#+id/masterLl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="foo bar"/>
</LinearLayout>
</ScrollView>
all works fine. I can see the three buttons on each layout.
But how can i add views like textview or button to the layout dynamicly?
Well the viewpager only supports 1 view inside each page, so in the adapter you modify the method:
public Object instantiateItem( View pager, int position )
you can create the view inside this method and return it to like this:
WebView web = new WebView(mContext);
return web;
Or if you need a more complex view than just an "Object" then you can create a linear layout, or something similar and add your other views inside and return that view like this:
LinearLayout layout = new LinearLayout(mContext);
WebView web = new WebView(mContext);
Button btn = new Button(mContext);
layout.addView(web);
layout.addView(btn);
return layout;
Hope it helps.
UPDATE:
Well right now i am doing something similar, i make the view that i will add to the viewpager dynamic, so depending on the type of an object i determine what is going to be inside.
I do not know how you plan to determine how a page must look, but i will tell you how i do it.
I have a list of "Objects", and those objects extends from a Class (You can also do it with interface and implementation, i do it with extends for other reasons) in common, and that class have a method "public View getView()" and the in all the Classes that extends from the Father Class (or Implemented the Interface), you Override (Implement) the method and add the code necessary to make that "PAGE" look like you want, then on the adapter you only need to have a list of "Objects" of any of the classes that you created and depending on which type each of those "Objects" are they will create the View passed to the ViewPager.
EXAMPLE:
Dog //CLASS OR INTERFACE WITH METHOD getView()
-Chihuahua //This return a WebView
-Sharpei //This return a HorizontalListView
-Huskie //This return a LinerLayout with a Bunch of Views Inside
on your adapter:
public class ViewPagerAdapter extends PagerAdapter {
List<Dog> Doggies = new ArrayList<Dog>();
public ViewPagerAdapter( Context context ){
Doggies.add(new Chihuahua());
Doggies.add(new Sharpei());
Doggies.add(new Chihuahua());
Doggies.add(new Huskie());
Doggies.add(new Huskie());
Doggies.add(new Chihuahua());
Doggies.add(new Sharpei());
}
//and last but not least, on your onCreate method in your adapter:
public Object instantiateItem( View pager, int position ){
return Doggies.get(position).getView();
}
/*THE REST OF THE METHODS GOES AFTER THIS*/
} //END OF ADAPTER
Related
I am working on an android application and using viewpager in a view. I am using PagerAdapter to show the views of tabs in viewpager.
I have to add/remove some Tabs dynamically. When I am adding any tab along with it's view then instantiateItem function is being called and tab is getting added successfully. But When I remove any tab from viewpager then destroyItem function should be called but it is not getting called and the view of Tab is not getting removed.
This the code which I am using to add/remove tabs.
public List<View> viewsList = new ArrayList();
public HashMap<Integer, View> GridViewList = new HashMap<>();
MyAdapter myAdapter = new MyAdapter();
viewPager.setAdapter(myAdapter);
viewPager.setOffscreenPageLimit(myAdapter.getCount() + 1);
private class MyAdapter extends PagerAdapter {
public MyAdapter() {
super();
}
#Override
public int getCount() {
return viewsList.size();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View v = viewsList.get(position).rootView;
container.addView(v, 0);
return v;
}
#Override
public void destroyItem(ViewGroup container, int position, Object view) {
container.removeView((View)view);
}
#Override
public boolean isViewFromObject(View view, Object key) {
return key == view;
}
}
I am adding using the below method When I add any Tab along with it's view
View view = new View(); // I am making Custom View here
viewsList.add(view);
GridViewList.put(Id, view);
myAdapter.notifyDataSetChanged();
And When I remove any view, I use below method :
viewsList.remove(GridViewList.get(Id));
GridViewList.remove(Id);
myAdapter.notifyDataSetChanged();
But the destroyItem function is not being called when I remove any Tab and it's view from adapter in android. Please help me if someone have any idea about this.
Thanks a lot in advanced.
Late to the party, but: you need to implement getItemPosition in order for destroyItem to be called. In this case, something like this should work:
#Override public int getItemPosition(Object itemIdentifier) {
int index = viewsList.indexOf(itemIdentifiers);
return index == -1 ? POSITION_NONE : index;
}
I try to implement Fragment into ViewPager to make my app more flexible. My app contains TextView and I have a few phrases that will appear one by one if you swap the page from left to right. For now it works in this way like I posted but I want to add a button or maybe some more function, that's why I want to make it like constructor from Fragments.. I try to change my code watching on this post but can't totally understand how to do it. I created two layouts: one for text view another one to put there fragment. Could any one show me how to do it clear?
public class SwipeAdapter extends PagerAdapter{
private int[] car = {R.string.car1, R.string.car2,
R.string.car3, R.string.car4, R.string.car5};
private Context context;
private LayoutInflater layoutInflater;
public SwipeAdapter(Context context){
this.context = context;
}
#Override
public int getCount() {
return car.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view==(RelativeLayout)object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = layoutInflater.inflate(R.layout.carSwipe, container, false);
TextView textView = (TextView) itemView.findViewById(R.id.interTextView);
textView.setText(car[position]);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((RelativeLayout)object);
}
You don't need ViewPager with Fragments to Achieve of showing a TextView.
You can try:
In your activity layout xml that you set in content View add a ViewPager with width and height of your preference.
Then you can set the adapter that you have posted above for that ViewPager and it will work.
Alternatively if you still need to inflate Fragments then you need to extend FragmentStateAdapter of FragmentAdapter. That will give you the ability to have in the ViewPager Fragment,
i Want to make a slideshow with viewpager where pages are changed automatically every 5 sec. Ive done the viewpager , but got blocked till here , any advise??
Adapter.class (its inner class in my fragment)
class CustomPagerAdapter extends PagerAdapter {
Context mContext;
LayoutInflater mLayoutInflater;
public CustomPagerAdapter(Context context) {
mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mResources.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View itemView = mLayoutInflater.inflate(R.layout.slide_show_item, container, false);
ImageView imageView = (ImageView) itemView.findViewById(R.id.imageView);
imageView.setImageResource(mResources[position]);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}
}
Here is the function i call in my fragment
public void setSlideShow(){
mCustomPagerAdapter = new CustomPagerAdapter(getActivity());
mViewPager = (ViewPager)rootView.findViewById(R.id.slide_show);
mViewPager.setAdapter(mCustomPagerAdapter);
}
Well, android does not provide any function to automatically flip views inside ViewPager but it provides you with something called TimerTask class which you can use to achieve your goal.
You can look at this link to do it this way.
There is one more easy way to achieve this but for that you will have to drop the idea of using ViewPager. Instead you can use ViewFlipper.
ViewFlipper has its own methods to flip automatically. You just need to add these two lines to make your views automatically flippable:
mViewFlipper.setAutoStart(true);
mViewFlipper.setFlipInterval(2000); // flip every 2 seconds (2000ms)
You can get ViewFlipper example here.
I'm trying to implement ViewPager to combine two view within one activity, in which I'm facing NullPointerException when I'm trying to access items using findViewById in inflated views, my custom page adapter is as follows,
public class CustomPagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 2;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
}
#Override
public void destroyItem(View view, int value, Object object) {
((ViewPager) view).removeView((View) object);
}
#Override
public Parcelable saveState() {
return null;
}
#Override
public Object instantiateItem(View collection, int position) {
LayoutInflater layoutInflater = (LayoutInflater) collection.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int resultId = 0;
switch (position) {
case 1:
resultId = R.layout.layout2;
break;
case 0:
default:
resultId = R.layout.layout1;
break;
}
View view = layoutInflater.inflate(resultId, null);
((ViewPager) collection).addView(view, 0);
return view;
}
}
And my activity is as follows, in which I'm trying to access button which is inside layout1 which throws null value.
public class PageSwiperActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewpagerlayout);
Button myButton=(Button) findViewById(R.id.myButton);
}
}
My viewpagerlayout.xml contains only,
<android.support.v4.view.ViewPager
android:id="#+id/viewPagerLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
and my layout1.xml contains one button. Give me some guidance.
Thanks.
Did you set your PageAdapter to ViewPager?
If you don't set it, then remove line with button and add this code to your activity:
final ViewPager viewPager = (ViewPager) findViewById(R.id.viewPagerLayout);
viewPager.setAdapter(new CustomPagerAdapter());
instead of this
Button myButton = (Button) findViewById(R.id.myButton);
You can call findViewById to get your button in this method of your adapter:
#Override
public Object instantiateItem(View collection, int position) {
... // your previous code
final Button myButton = (Button) findViewById(R.id.myButton);
return view;
}
after you have inflated layout which contains this button.
After setContentView(R.layout.viewpagerlayout);
you are using
Button myButton=(Button) findViewById(R.id.myButton); directly.
But actually viewpagerlayout doesn't have any view with id myButton.
So that you are getting NULL Pointer Exception. Before using findViewById, you have to add views to ViewPager layout.
In the code you posted here, it seem to be you are adding, but you have to use it after setContentView.
I want to use three previously created Activities in a ViewPager (with PagerAdapter) so the user can scroll smoothly horizontally through them.
I followed a tutorial which worked great. The problem is in the tutorial they use TextViews to demonstrate. I already have finished Activities (of which the layouts are in XML files). I want to use these Activities in that slider now but it looks like I can only use Views for that.
I could not figure out how I have to change the code of the classes (from "implements Activity" to "extends View") that I can use it in the slider.
The my current code looks like this:
public class HorizontalSliderBeispielActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cxt = this;
awesomeAdapter = new AwesomePagerAdapter();
awesomePager = (ViewPager) findViewById(R.id.awesomepager);
awesomePager.setAdapter(awesomeAdapter);
}
...
then the inner class with the PageAdapter:
...
private class AwesomePagerAdapter extends PagerAdapter {
public Object instantiateItem(View collection, int position) {
TextView tv = new TextView(cxt);
tv.setText("Bonjour PAUG " + position);
tv.setTextColor(Color.WHITE);
tv.setTextSize(30);
view_01 = new SubmitCheatInstructions(cxt);
((ViewPager) collection).addView(tv, 0);
((ViewPager) collection).addView(view_01 , 1);
return tv;
}
}
Instead of that TextView "tv" I want to use Activities (i.e. SubmitCheatInstructions). Previously this class looked like:
public class SubmitCheatInstructions implements Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.submitcheat_instructions);
}
}
but as far as I know I have to change it to
public class SubmitCheatInstructions extends View {
????
}
in order to be able to use it for the ViewPager.
My problem now is that I want to load the layout from the layout xml file (submitcheat_instructions.xml) into that view and not do everything in code. I could not figure out how I have to do this.
Thanks for any help.
I followed the same tutorial and like you i was unable to achieve this at first but after some tinkering and trial and error the following code worked like a charm:
/**
* Create the page for the given position. The adapter is responsible
* for adding the view to the container given here, although it only
* must ensure this is done by the time it returns from
* {#link #finishUpdate()}.
*
* #param container
* The containing View in which the page will be shown.
* #param position
* The page position to be instantiated.
* #return Returns an Object representing the new page. This does not
* need to be a View, but can be some other container of the
* page.
*/
#Override
public Object instantiateItem(View collection, int position) {
View v = new View(PatientView.this.getApplicationContext());
final LayoutInflater inflater = (LayoutInflater) PatientView.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (position) {
case 0:
v = inflater.inflate(R.layout.patientp1,
(ViewGroup) null, false);
((Button) v.findViewById(R.id.pp1btnbck)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
finish();
}
});
break;
case 1:
v = inflater.inflate(R.layout.patientp2, null, false
);
break;
default:
TextView tv = new TextView(PatientView.this.context);
tv.setText("Page " + position);
tv.setTextColor(Color.WHITE);
tv.setTextSize(30);
v = tv;
break;
}
((ViewPager) collection).addView(v, 0);
return v;
}
Hope this helps, Good luck
Shereef Marzouk
Thanks Shereef. Your code was really useful.
I wanted to pass data from my main activity to the different layout's in ViewPager. I got the idea from your code where you are setting the onClickListener for the button. That helped me to pass data generated in the main activity to the different TextView's in different layout's.
public Object instantiateItem(View collection, int position)
{
View v = new View(CalcTimeActivity.this.getApplicationContext());
collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final LayoutInflater inflater = (LayoutInflater) CalcTimeActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch (position) {
case 0:
v = inflater.inflate(R.layout.N, (ViewGroup) null, false);
((TextView) v.findViewById(R.id.tvA)).setText(strA);
((TextView) v.findViewById(R.id.tvB)).setText(strB);
((TextView) v.findViewById(R.id.tvC)).setText(strC);
break;
case 1:
v = inflater.inflate(R.layout.M, null, false);
break;
case 2:
v = inflater.inflate(R.layout.F, null, false);
break;
}
((ViewPager) collection).addView(v, 0);
return v;
}