#Override
public Object instantiateItem(View pager, int position) {
ViewGroup view = new ViewGroup(mContext) {
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
};
view.setBackgroundColor(Color.BLUE);
View view2 = new View(mContext);
LayoutParams lp = new LayoutParams(200, 200);
view2.setLayoutParams(lp);
view2.setBackgroundColor(Color.BLACK);
view.addView(view2);
((ViewPager)pager).addView(view, 0);
return view;
}
Is it possible?
If not, how can I add a ViewGroup to a ViewPager?
Please, help me out.
You should use FragmentPagerAdapter to add fragment to ViewPager.
Fragments can contain any viewgroups.
Related
In my activity I have a OnPageChangeListener and view Pager implemented.
On onPageSelectedin function I call function name viewPagerHandler, when I have all the logic for single viewPager Page (Buttons, actions depended of current page etc.)
public class ActivityClass extends Activity implements ViewPager.OnPageChangeListener, View.OnClickListener{
protected void onCreate(Bundle savedInstanceState) {
viewPager=(ViewPager)findViewById(R.id.Pager);
adapter= new
ViewPageAdapter(ActivityClass.this,list,imagesList);
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(0);
viewPager.addOnPageChangeListener(ActivityClass.this);
}
#Override
public void onClick(View v) {
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
this.position=position;
viewPagerHandler(viewPager.findViewWithTag(position),position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
public View viewPagerHandler(final View view, final int position){
//ALL LOGIC BUTTONS ACTIONS ETC.
view.invalidate();
return view;
}
}
public class ViewPageAdapter extends PagerAdapter{
#Override
public Object instantiateItem(final ViewGroup container, final int position) {
final View itemView = LayoutInflater.from(mContext).inflate(R.layout.art_work_item, container, false);
itemView.setTag(position);
container.add(itemView); // edited after suggested
if(mContext instanceof ActivityClass && position==0) //The page listener in ActivityClass is trigger only when page is changed so i tried to hack it when the viewPager is instantiate for the first time
return ((ActivityClass) mContext).viewPagerHandler(itemView,position);
return itemView;
}
}
EDIT: The logic works perfectly on the first and the last item. For rest of them the view is not refreshing (however its still working, because i have buttons which changing color after clicked, when I click on them and then slide to next item and back to the previous one the color is changed so its trigger)
You are missing the line in the instantiateItem() method,
public Object instantiateItem(final ViewGroup container, final int position) {
final View itemView = LayoutInflater.from(mContext).inflate(R.layout.art_work_item, container, false);
itemView.setTag(position);
container.addView(itemView);
if(mContext instanceof ActivityClass && position==0) //The page listener in ActivityClass //is trigger only when page is changed so i tried to hack it when the viewPager is //instantiate for the first time
return ((ActivityClass) mContext).viewPagerHandler(itemView,position);
return itemView;
}
I have used viewpager which displays view with an image and radiobutton below. Each swipe screen is not a fragment, they are layouts which just swipe the same view with different imageview. The problem is that, I am unable to deselect the radio button which is in left and right side of the current view after i select the radio button of the current screen. If I return POSITION_NONE in getItemPosition(), it refresh the screen and radio button also deselected but the view is flickered. If i am able to call instantiateItem(), my problem is solved . But this method is called only when view is destroyed based on the setOffsetScreenPageLimit(). How can I achieved such requirements, if view pager cannot help?
Fragment:
public class AnswerImageDialogFragment extends DialogFragment implements ViewPager.OnPageChangeListener {
//member declaration
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strQuestion = null;
View rootView = inflater.inflate(R.layout.activity_viewpager_demo, container,
false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
intro_images = (ViewPager) rootView.findViewById(R.id.pager_introduction);
pager_indicator = (LinearLayout) rootView.findViewById(R.id.viewPagerCountDots);
//do some stuff
//set the adapter
mAdapter = new ViewPagerAdapter(getContext(), map);
intro_images.setAdapter(mAdapter);
intro_images.setCurrentItem(clickPosition);
intro_images.setOnPageChangeListener(this);
setUiPageViewController();
bus = EventBus.getDefault();
bus.register(this);
return rootView;
}
//other method
}
PagerAdapter:
public class ViewPagerAdapter extends PagerAdapter {
// member declaration
public ViewPagerAdapter(Context mContext, HashMap<String, Object> map) {
//other initialization
}
#Override
public int getCount() {
return optionImages.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.pager_item, container, false);
final ImageView ivOption = (ImageView) itemView.findViewById(R.id.answerId); // this is used as radio button in this case
/*The code snippet is to select the answer option based on whether answer is choosen or not.
If choosen, select as default in the pop up answer.
*/
if (null != ans) {
Iterator iterator = ans.iterator();
if (ans.size() > 0) {
int value = (int) iterator.next();
if (value == position) {
ivOption.setImageResource(R.drawable.ic_radio_button_tick);
} else {
ivOption.setImageResource(R.drawable.ic_radio_button_nontick);
}
}
}
p = position;
/*The code snippet is to change the answer value based on the user selection.
This means if user choosen another answer then clear the earlier choosen answer
*/
ivOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do stuff
}
});
txtQuestion.setText(question);
txtOption.setText(optionsList.get(position));
imageView.setParseFile(optionImages.get(position));
imageView.loadInBackground();
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
LinearLayout ll = (LinearLayout) object;
/*RelativeLayout ivOption = (RelativeLayout) ll.getChildAt(2);
ImageView iv = (ImageView) ivOption.getChildAt(1);
iv.setImageResource(R.drawable.ic_radio_button_tick);*/
container.removeView(ll);
}
#Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
public void refresh(ArrayList object) {
this.object = new ArrayList();
this.object.addAll(object);
this.notifyDataSetChanged();
}
I am in a need of nested viewPagers, I am using a custom vertical viewPager where its child is a viewPager.
My problem is when the user swipes in vertical direction (Y axis) parent viewpager should function and if he swipes in horizontal (X axis) child viewpager has to function.
I came across a lot of tutorial where I can disable either parent's swipe or child's swipe but I dont want to do that, instead according to the swipe direction either parent (vertical) should work and child (horizontal) has to work.
I have also attached parent's viewpager adapter code here
class VerticalPageAdapter extends PagerAdapter
{
Context mContext;
LayoutInflater mLayoutInflater;
public VerticalPageAdapter(Context context)
{
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount()
{
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object)
{
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position)
{
mVerticalViewPagerPosition = position;
View itemView = mLayoutInflater.inflate(R.layout.homelayout_verticalpager, container, false);
mPager = (ViewPagerTest)itemView.findViewById(R.id.pager);
mPager.setAdapter(new NewsPageAdapter(mContext));
mPager.setOnTouchListener(gestureListener);
mPager.getParent().requestDisallowInterceptTouchEvent(false);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object)
{
container.removeView((LinearLayout) object);
}
}
Please help to sort out this.
I would like to create a ViewPager whose width wrap's to its contents, and is centered horizontally in it's parent. The first code snippet uses a LinearLayout to create this effect, as shown in the first screenshot. The second code snippet is my attempt to do this with a ViewPager instead of the LinearLayout, but the result is not the desired behavior, as shown in the second screenshot.
Any suggestions as to how I create the first effect, but using a ViewPager?
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
textView = new TextView(this);
textView.setLayoutParams(new ViewGroup.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
textView.setText("abcabcabcabcabc");
textView.setBackgroundColor(Color.YELLOW);
LinearLayout llayout = new LinearLayout(this);
llayout.setBackgroundColor(Color.BLUE);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.MATCH_PARENT);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
llayout.setLayoutParams(layoutParams);
llayout.addView(textView);
layout = new RelativeLayout(this);
layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
layout.setBackgroundColor(Color.GREEN);
layout.addView(llayout);
setContentView(layout);
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
textView = new TextView(this);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewPager.LayoutParams.WRAP_CONTENT, ViewPager.LayoutParams.WRAP_CONTENT));
textView.setText("abcabcabcabcabc");
textView.setBackgroundColor(Color.YELLOW);
ViewPager pager = new ViewPager(this);
pager.setBackgroundColor(Color.BLUE);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.FILL_PARENT);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
pager.setLayoutParams(layoutParams);
pager.setAdapter(new ViewPagerAdapter());
layout = new RelativeLayout(this);
layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
layout.setBackgroundColor(Color.GREEN);
layout.addView(pager);
setContentView(layout);
}
class ViewPagerAdapter extends PagerAdapter
{
#Override
public int getCount()
{
return 1;
}
public Object instantiateItem(ViewGroup collection, int position)
{
collection.addView(textView, 0);
return textView;
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view)
{
collection.removeView((View) view);
}
#Override
public boolean isViewFromObject(View view, Object object)
{
return (view==object);
}
#Override
public void finishUpdate(ViewGroup arg0) {}
#Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {}
#Override
public Parcelable saveState()
{
return null;
}
#Override
public void startUpdate(ViewGroup arg0) {}
}
If you look at your code for where Adapter called instantiateItem()
public Object instantiateItem(ViewGroup collection, int position)
{
collection.addView(textView, 0)
return textView;
}
You are returning a TextView to be the page and the ONLY thing that you want to show.
The relevant part of the documentation is here:
http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html
A very simple PagerAdapter may choose to use the page Views themselves
as key objects, returning them from instantiateItem(ViewGroup, int)
after creation and adding them to the parent ViewGroup. A matching
destroyItem(ViewGroup, int, Object) implementation would remove the
View from the parent ViewGroup and isViewFromObject(View, Object)
could be implemented as return view == object;.
Create a View with the layout that you want and return it there to have the effect you desire.
See the bottom of:
http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html
My note application has 2 fragments on a screen: A list of notes fragment and a note detail fragment to display the selected note in the second fragment, it has an input text field (android:inputType="textMultiLine"). As I want to handle event keyboard hidden so I can save the change user has made when they close the keyboard. Can anyone give me a clue to do this task?
I think that the best and universal solution for keyboard issue, is measure the VisibleDisplayFrame on layout change:
Rect visibleRect = new Rect();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup mMain = (ViewGroup) inflater.inflate(R.layout.select_cover_album, container, false);
mMain.getWindowVisibleDisplayFrame(visibleRect);
mMain.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v,
int left,
int top,
int right,
int bottom,
int oldLeft,
int oldTop,
int oldRight,
int oldBottom) {
Rect r = new Rect();
mMain.getWindowVisibleDisplayFrame(r);
if(r.height() < visibleRect.height()){
//keyboard shown
}
if(r.height() == visibleRect.height()){
//keyboard hidden
}
}
});
return mMain;
}
Here's how i handle it on my Note Detail fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
this.view = inflater.inflate(R.layout.fragment_note_detail_of_style_searching, container , false);
listviewFilter = (ListView) view.findViewById(R.id.listview_filter);
noteDetailView = view.findViewById(R.id.note_detail_of_style_view);
photoDetailView = view.findViewById(R.id.gv_note_detail_photo);
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int heightDiff = view.getRootView().getHeight() - view.getHeight();
if (heightDiff > 200) {
isWatchingKeyboard = true;
photoDetailView.setVisibility(View.GONE);
return; //must exit now
}
if(isWatchingKeyboard){
isWatchingKeyboard = false;
viewForFocus.requestFocus();
photoDetailView.setVisibility(View.VISIBLE);
}
}
});
return this.view;
}
I did it this way:
private int prevBottom;
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_status, container, false);
prevBottom = view.getBottom();
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (view.getBottom() > prevBottom) {
view.requestFocus();
}
prevBottom = view.getBottom();
}
});
return view;
}
and added this to the view I was inflating:
android:focusableInTouchMode="true"
and this to the activity in the AndroidManifest.xml
android:windowSoftInputMode="adjustResize"