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();
}
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;
}
When i am using simple imageview or AspectRatioImageView I am able to load images fetched from server. But if I am using TouchImageView or GestureImageView it is not able to load images. I see a blank screen.
Apart from using UIL,I have tried some other ways of loading images also but same result.
However when i have opened a view in viewpager and its not showing image..then if i switch to landscape mode and then again to portrait mode then it is able to load image..If i call notifyDataSetChanged() anywhere inside adapter it crashes showing InflateException
xml
<com.polites.android.GestureImageView
android:id="#+id/imagefullscreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_gravity="center"/>
Activity
pager.setAdapter(imagePagerAdapter = new ImagePagerAdapter(ImagePagerActivity.this, posts));
pager.setCurrentItem(pos);
PageListener pageListener = new PageListener();
pager.setOnPageChangeListener(pageListener);
imagePagerAdapter.notifyDataSetChanged();
Adapter
public ImagePagerAdapter(Activity activity,
List<Post> object) {
this._activity = activity;
posts = object;
inflater = (LayoutInflater) _activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
options = new DisplayImageOptions.Builder()
.showImageOnLoading(android.R.color.transparent)
.showImageForEmptyUri(android.R.color.transparent)
.showImageOnFail(android.R.color.transparent)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(_activity));
}
#Override
public int getCount() {
return posts.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
final Post post = posts.get(position);
View viewLayout = inflater.inflate(R.layout.item_pager_image, container,
false);
visualizerView = (VisualizerView) viewLayout.findViewById(R.id.visualizerView);
image = (GestureImageView) viewLayout.findViewById(R.id.imagefullscreen);
mGDescription = (TextView) viewLayout.findViewById(R.id.guggu_pager_description);
image.setVisibility(View.VISIBLE);
mGDescription.setVisibility(View.VISIBLE);
play = (ImageView) viewLayout.findViewById(R.id.play);
pause = (ImageView) viewLayout.findViewById(R.id.pause);
imageLoader.displayImage(url,images, options);
pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//TODO:pausing audio/video here
}
});
}
container.addView(viewLayout);
viewLayout.setTag("my" + position);
return viewLayout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
The issue was because TouchImageView or GestureImageView is taking time to load image from server and view was not updated after image is being loaded.
I added-
private class PageListener extends ViewPager.SimpleOnPageChangeListener
{
public void onPageSelected(int position)
{
imagePagerAdapter.notifyDataSetChanged();
}
}
inside activity class so that view is updated whenever user swipe to new page.But with this the first view that I was opening was still showing blank..so i added
h.postDelayed(r=new Runnable()
{
#Override
public void run() {
if (mPosition == position)
{
notifyDataSetChanged();
h.removeCallbacks(r);
}
}
}, 1000);
inside instantiateItem of adapter so that first view is updated after 1 second when view is created as by that time image is fetched from server.mPosition is the position of first view that is being opened.
This completely solves my issue.
I've a gridview with clickable items. When I click on an item the gridview is became hidden and I show a ViewPager.
In my case this ViewPager should work like slideshow.
So I've tried to follow the Google example here: http://developer.android.com/training/animation/screen-slide.html
If I open a new activity on gridview item click, the viewpager is working well (like the Google example). But if I open the ViewPager hiding the gridview the slide animation become lagging.
Obviously I've tried to open the viewpager with same graphics/bitmaps etc..
Unfortunately my application need to work in the same activity, and I cannot open a new one.
Is there some limitations about ViewPager? Or I should give attention on something particular?
Quite Simple.
Unfortunately my application need to work in the same activity, and I cannot open a new one.
I presume when a user click one of the grid view of the item (maybe containing image), a view pagers shows up with the image and the user can slide the ViewPager for next image and so on.
In this case, use a Dialog Fragment.
Layout for ViewPager's Image :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black">
<ImageView
android:id="#+id/image_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:scaleType="fitCenter" />
</RelativeLayout>
Dialog Fragment Code :
public class SlideshowDialogFragment extends DialogFragment {
private String TAG = SlideshowDialogFragment.class.getSimpleName();
private ArrayList<Image> images;
private ViewPager viewPager;
private MyViewPagerAdapter myViewPagerAdapter;
private TextView lblCount, lblTitle, lblDate;
private int selectedPosition = 0;
static SlideshowDialogFragment newInstance() {
SlideshowDialogFragment f = new SlideshowDialogFragment();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_image_slider, container, false);
viewPager = (ViewPager) v.findViewById(R.id.viewpager);
lblCount = (TextView) v.findViewById(R.id.lbl_count);
lblTitle = (TextView) v.findViewById(R.id.title);
lblDate = (TextView) v.findViewById(R.id.date);
images = (ArrayList<Image>) getArguments().getSerializable("images");
selectedPosition = getArguments().getInt("position");
Log.e(TAG, "position: " + selectedPosition);
Log.e(TAG, "images size: " + images.size());
myViewPagerAdapter = new MyViewPagerAdapter();
viewPager.setAdapter(myViewPagerAdapter);
viewPager.addOnPageChangeListener(viewPagerPageChangeListener);
setCurrentItem(selectedPosition);
return v;
}
private void setCurrentItem(int position) {
viewPager.setCurrentItem(position, false);
displayMetaInfo(selectedPosition);
}
// page change listener
ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
displayMetaInfo(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
};
private void displayMetaInfo(int position) {
lblCount.setText((position + 1) + " of " + images.size());
Image image = images.get(position);
lblTitle.setText(image.getName());
lblDate.setText(image.getTimestamp());
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
}
// adapter
public class MyViewPagerAdapter extends PagerAdapter {
private LayoutInflater layoutInflater;
public MyViewPagerAdapter() {
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.image_fullscreen_preview, container, false);
ImageView imageViewPreview = (ImageView) view.findViewById(R.id.image_preview);
Image image = images.get(position);
Glide.with(getActivity()).load(image.getLarge())
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageViewPreview);
container.addView(view);
return view;
}
#Override
public int getCount() {
return images.size();
}
#Override
public boolean isViewFromObject(View view, Object obj) {
return view == ((View) obj);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
}
Send the image link and its description/ title through this code:
Bundle bundle = new Bundle();
bundle.putSerializable("images", images);
bundle.putInt("position", position);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
SlideshowDialogFragment newFragment = SlideshowDialogFragment.newInstance();
newFragment.setArguments(bundle);
newFragment.show(ft, "slideshow");
The array List being used :
private ArrayList<Image> images = new ArrayList<>();
Image image = new Image();
image.setName("Image Title");
image.setLarge("ImageUrl");
Have a Linearlayout inside to that having 3 different framelayout. In that frame layout am adding the fragments dynamically inside the adaper getview. Initially the adapter getview gets called twice. Then later it called once for every flip. Have added the flip view functionality along with that. In that for first screen before any flip, the dynamic fragments are not getting added to the main view. But for the later flipped screens it's getting added properly.
Please help me on this.
Thanks in advance.
public class MainActivity extends Activity {
private FragmentTransaction fragMentTra = null;
protected FlipViewController flipView;
private LayoutInflater inflater;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
flipView = new FlipViewController(this);
flipView.setAdapter(new BaseAdapter() {
public int getCount() {
return 2;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#SuppressLint("NewApi")
public View getView(int position, View convertView, ViewGroup parent) {
View layout = convertView;
if (convertView == null) {
inflater = LayoutInflater.from(parent.getContext());
layout = inflater.inflate(R.layout.activity_main, null);
AphidLog.d("created new view from adapter: %d", position);
}
NewsFragment[] newsFragment_obj = new NewsFragment[GlobalValues.titile.length];
fragMentTra = getFragmentManager().beginTransaction();
for (int i = 0; i < GlobalValues.titile.length; i++) {
newsFragment_obj[i] = new NewsFragment(
GlobalValues.titile[i], GlobalValues.content[i]);
AphidLog.d("Array Loc: %d", i);
}
fragMentTra.add(R.id.fragment_container1, newsFragment_obj[0],
"Fragment1");
fragMentTra.add(R.id.fragment_container2, newsFragment_obj[1],
"Fragment2");
fragMentTra.add(R.id.fragment_container3, newsFragment_obj[2],
"Fragment3");
fragMentTra.commit();
return layout;
}
});
setContentView(flipView);
}
I have a ListView that contains rows of ViewPagers. When a ViewPager is scrolled off screen, I want to save its page position. When the user scrolls to the ViewPager again, I then want to restore its last saved page position.
I'm trying to accomplish this with the following code:
public class MyBaseAdapter extends BaseAdapter {
// Row ids that will come from server-side, uniquely identifies each
// ViewPager
private List<String> mIds = new ArrayList<String>();
private Map<String, Integer> mPagerPositions = new HashMap<String, Integer>();
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String id = mIds.get(position);
View rootView = convertView;
if (rootView == null) {
rootView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.row, null);
}
ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.pager);
Integer pagerPosition = mPagerPositions.get(id);
if (pagerPosition != null) {
viewPager.setCurrentItem(pagerPosition);
}
viewPager.setOnPageChangeListener(new MyPageChangeListener(id));
return rootView;
}
#Override
public int getCount() {
return mIds.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
private class MyPageChangeListener extends
ViewPager.SimpleOnPageChangeListener {
private String mId;
public MyPageChangeListener(String id) {
mId = id;
}
#Override
public void onPageSelected(int position) {
mPagerPositions.put(mId, position);
}
}
}
The page position gets saved on the first invocation of setPagerPosition(). Afterwards, when the ViewPager goes off-screen, onPageSelected() is called with the first page position that was saved — overwriting any previous onPageSelected() calls that occurred when the ViewPager was still visible.
What's the right way to do this?
The solution was to not overwrite the pager position when the ViewPager is not visible. There appears to be a bug in Android where onPageSelected is called when the ViewPager goes off screen when scrolling through the ListView.
#Override
public void onPageSelected(int position) {
if (viewPager.isShown()) {
mTopicPositions.put(mId, position);
}
}
I think you can get the current displayed position by indexOfChild(viewPager.getFocusedChild()) and store it in a shared preference, and can retrieve it whenever required. Hope this helps