Can I use ViewPager inside custom InfoWindowAdapter? - android

I'm using a InfoWindowAdapter within Google Maps API2. My XML layout has some simple TextView and ImageView views, but I also need a ViewPager to allow the users to swipe a series of custom layouts associated with the marker on the map (an image and some text). My InfoWindow layout is:
spot_window_complex.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_relative_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/transparent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/lin1"
android:layout_width="275.0dip"
android:layout_height="140.0dip"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="275.0dip"
android:layout_height="85.0dip"
android:background="#drawable/round" />
<LinearLayout
android:layout_width="275.0dip"
android:layout_height="40.0dip"
android:background="#ffeeeeee"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="10.0dip"
android:paddingTop="10.0dip">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10.0dip"
android:paddingRight="3.0dip"
android:src="#drawable/clock" />
<ImageButton
android:id="#+id/imgThumbsUp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffeeeeee"
android:paddingRight="3.0dip"
android:src="#drawable/thumbsup" />
<TextView
android:id="#+id/txtPve"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="50.0dip"
android:textColor="#ff29c200"
android:textStyle="bold" />
<ImageButton
android:id="#+id/imgThumbsDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffeeeeee"
android:paddingRight="3.0dip"
android:src="#drawable/thumbsdown" />
<TextView
android:id="#+id/txtNve"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffc91c11"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
I've created a simple XML layout to try to get the ViewPager working within the InfoWindowAdapter:
viewpager_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:padding="10dp" >
<TextView
android:id="#+id/countrylabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Country: " />
<TextView
android:id="#+id/country"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/countrylabel" />
</RelativeLayout>
My ViewPagerAdapter seems pretty standard:
class ViewPagerAdapter extends PagerAdapter {
LayoutInflater inflater;
String[] country = new String[]{"China", "India", "United States","Indonesia",
"Brazil", "Pakistan", "Nigeria", "Bangladesh", "Russia", "Japan"};
#Override
public int getCount() {
return country.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
inflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.viewpager_item, container,
false);
TextView txtcountry = (TextView) itemView.findViewById(R.id.country);
txtcountry.setText(country[position]);
((ViewPager) container).addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// Remove viewpager_item.xml from ViewPager
((ViewPager) container).removeView((RelativeLayout) object);
}
}
And my InfoWindowAdapter seems OK too:
public class SimpleInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
public SimpleInfoWindowAdapter() {
}
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
View v;
MySimpleMarker myMarker = mSimpleMarkersHashMap.get(marker);
v = getActivity().getLayoutInflater().inflate(R.layout.spot_window_complex, null);
TextView txtPve = (TextView) v.findViewById(R.id.txtPve);
TextView txtNve = (TextView) v.findViewById(R.id.txtNve);
txtPve.setText("0"); //test string only
txtNve.setText("0"); //test string only
ViewPager vPager = (ViewPager) v.findViewById(R.id.pager);
vPager.setAdapter(new ViewPagerAdapter());
return v;
}
}
The TextView and ImageView views that are static from the XML or are set by the adapter work fine, as does the general layout. However, my ViewPager, which should in this test case have 10 swipeable countries in TextViews, is blank. All the relevant code is being handled inside one fragment and there are no errors in the Android Monitor.
Any ideas what I've done wrong?

I also need a ViewPager to allow the users to swipe a series of custom layouts associated with the marker on the map
That is not possible.
Any ideas what I've done wrong?
The View you return from your InfoWindowAdapter is converted immediately into a Bitmap. That Bitmap is what winds up being rendered on the screen. Hence, you cannot have interactive widgets, like a ViewPager. Not only will they not be interactive, but anything that is rendered asynchronously (e.g., pages in a ViewPager) might not be rendered in time before the Bitmap is created.
Or, quoting the documentation:
Note: The info window that is drawn is not a live view. The view is rendered as an image (using View.draw(Canvas)) at the time it is returned. This means that any subsequent changes to the view will not be reflected by the info window on the map. To update the info window later (for example, after an image has loaded), call showInfoWindow(). Furthermore, the info window will not respect any of the interactivity typical for a normal view such as touch or gesture events. However you can listen to a generic click event on the whole info window as described in the section below.

Related

How to show one JSON Object per ViewPager in Android?

I am working on a short news app. It's parsed JSON from a URL. I want to show one news per view pager.on swipe on next ViewPager, I want to show next news like the list. How can I can do that with ViewPager?
Set JSON data to PagerAdapter as we set to Base Adapter or other adapters & create custom layout for adapter.
view_pager_layout.xml
<RelativeLayout
android:id="#+id/loutPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/loutCirIndicator"
android:background="#android:color/transparent"
android:padding="5dp"/>
<LinearLayout
android:id="#+id/loutCirIndicator"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_alignParentBottom="true"
android:background="#android:color/transparent"
android:gravity="center_vertical"
android:orientation="horizontal">
<me.relex.circleindicator.CircleIndicator
android:id="#+id/indicator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
app:ci_drawable="#drawable/bg_selected_indicator"
app:ci_drawable_unselected="#drawable/bg_unselected_indicator" />
</LinearLayout>
</RelativeLayout>
row_pager_item.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:adjustViewBounds="true"
android:clickable="false"
android:scaleType="centerInside" />
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="abc" />
</LinearLayout>
ViewPager Adapter
public class SamplePagerAdapter extends PagerAdapter {
Activity activity;
List<Response_Model> Arr_ResultList;
ImageView imageView;
TextView textView;
public SamplePagerAdapter(final Activity activity,final List<Response_Model> Arr_ResultList) {
this.activity = activity;
this.Arr_ResultList = Arr_ResultList;
}
#Override
public int getCount() {
return Arr_ResultList.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
final int pos = position;
View view = LayoutInflater.from(container.getContext()).inflate(R.layout.row_pager_item, container, false);
imageView = (ImageView) view.findViewById(R.id.imageView);
textView = (TextView) view.findViewById(R.id.textView);
Glide.with(activity).load(Arr_ResultList.get(pos).getImage())
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
textView.setText(Arr_ResultList.get(pos).getName());
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}
Set Pager Adapter to ViewPager
SamplePagerAdapter pagerAdapter = new SamplePagerAdapter(MainActivity.this, Arr_Result_List);
viewPager.setAdapter(pagerAdapter);
indicator.setViewPager(viewPager);
You can use PagerAdapter for ViewPager and create your custom xml layout and
set your view on cell by position. Pass your list into pager adapter in adapter constructor.
You can refer this link it will be help you.
https://www.journaldev.com/10096/android-viewpager-example-tutorial

Scrollable PagerAdapter

I did a PagerAdapter, and it works very well but when I put my phone horizontally, many things like TextView are not visible, because they are "below" the screen of the phone. I know I could put a ScrollView, but this option gives a lot of errors.
Is there another option besides the ScrollView or what does the error mean?
This is my code with the LinearLayout without any errors but the PagerAdapter isn't scrollable.
Java code:
public class SlideAdapter_info extends PagerAdapter {
Context context;
LayoutInflater inflater;
public SlideAdapter_info(Context context){
this.context = context;
}
#Override
public int getCount() {
return 1;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view==(LinearLayout)object);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object{
container.removeView((LinearLayout)object);
}
#NonNull
#Override
public Object instantiateItem(ViewGroup container, int position) {
inflater = (LayoutInflater)
context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.slide_info, container, false);
//other code to set the textviews and the imageview
container.addView(view);
return view;
}
}
xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/slidelinear_info"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView /> ....
<!-- This allows me to have a circle shaped image-->
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/slideimg"
android:layout_width="200dp"
android:layout_height="200dp"
android:paddingTop="10dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
app:civ_border_color="#color/black"
app:civ_border_width="3dp" />
<TextView /> ....
</LinearLayout>
This is the result: (horizontal)
This is the result:(vertical)
If instead of LinearLayout I put the ScrollView, Android Studio gives me this error:
java.lang.IllegalStateException: ScrollView can host only one direct child
at esame.progetto.xhondar.github.com.info.SlideAdapter_info.instantiateItem(SlideAdapter_info.java:87)
This is the row:
View view = inflater.inflate(R.layout.slide_info, container, false);
java.lang.IllegalStateException: ScrollView can host only one direct child is telling you exactly what your problem is. By just converting your LinearLayout to a ScrollView, you have multiple children. If you want your current layout to be scrollable within your ViewPager, you need to wrap your LinearLayout with the ScrollView in your layout xml file.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/slidelinear_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<TextView /> ....
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/slideimg"
android:layout_width="200dp"
android:layout_height="200dp"
android:paddingTop="10dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
app:civ_border_color="#color/black"
app:civ_border_width="3dp" />
<TextView /> ....
</LinearLayout>
</ScrollView>

Fragments, Cards, ListViews and Images

It has been a long time since I did some Android and now I want to get back to it. I still try to grasp the concept of using Fragments properly and what would be the proper way to do what I need to.
To the point. I need to have a Main view that (for now) contains one card. This card will contain a TextView and a ListView with custom items(one image and two rows of text). How would I implement this?
Do I need to do a different fragment for the listView and another for the card? I know I need a custom Adapter for the list view but how do I go on putting everything together?
Any advice is welcomed, even in the most basic diagram form.
fragment_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
tools:context=".MainActivity$PlaceholderFragment"
android:paddingLeft="5dp"
android:paddingTop="10dp"
android:paddingRight="5dp"
android:paddingBottom="10dp">
<android.support.v7.widget.CardView
android:id="#+id/accounts_card"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_gravity="top"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="150dp"
android:layout_marginLeft="5dp"
card_view:cardCornerRadius="0dp"
card_view:cardBackgroundColor="#color/white"
card_view:cardElevation="3dp"
android:layout_marginRight="5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/accounts_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="#style/Base.TextAppearance.AppCompat.Caption"
android:elevation="1dp"
android:text="My Accounts"
android:gravity="top|center"
android:textStyle="bold"
android:textSize="20dp"
android:paddingTop="15dp"
android:paddingBottom="15dp" />
<ListView
android:id="#+id/accounts_list"
android:layout_below="#id/accounts_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
my_listitem.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/account_item">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/b_logo"
android:elevation="1dp"/>
<LinearLayout
android:layout_alignEnd="#id/b_logo"
android:paddingLeft="2dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right">
<TextView
android:id="#+id/account_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9959593922923"/>
<TextView
android:id="#+id/account_code"
android:layout_below="#id/account_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="30-15-55"/>
</LinearLayout>
</RelativeLayout>
First of all, if you want to have different navigatable cards containing text and list views, I would recommend using a PageAdapter , in which each card can be loaded to the adapter in the beginning of the Activity like this:
public class CustomAdapter extends PagerAdapter {
#Override
public Object instantiateItem(ViewGroup collection, int position) {
mContext=collection.getContext();
LayoutInflater inflator=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=inflator.inflate(R.layout.fragment_main, null);
//do things to initiate the card like loading a text by accessing the text through TextView tv=(TextView)view.findElementsById(R.id.accounts_title);
return view;
}
And for the List in your card, create a New subclass of Base Adapter Class and instantiate the layout my_listitem.xml there and return the view for each item in list , this can be done like this:
public class CustomListAdapter extends BaseAdapter {
private static List<?> list;
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout layout = null;
salahLayout=(RelativeLayout) LayoutInflater.from(mContext).inflate(R.layout.my_listitem, null);
notifyDataSetChanged();// to notify the list has been changed
return layout;
}
}
You may need to set the List in the CustomListAdapter Class using some setter method and then in the getView method you can create the view for each item in the list Item using the list.
To use the CustomListAdapter as the adapter for your list in the card in CustomAdapter class add this:
ListView list=(ListView)view.findElementById(R.id.accounts_list);
list.setAdapter(mCustomListAdapter);//set the object of the customlistadapter class
Fragments are used for changing part of Main UI .Refer the Below link:http://developer.android.com/guide/components/fragments.html

Android - ViewPager inside a Fragment not using Fragments

I have a Fragment, and I want to have a ViewPager inside of it, but only want part of the page to be a ViewPager, so I'm not making the ViewPager the contentView of the Activity. I'm having a couple problems: I don't know where to "fill in" my view, and I don't know what to do in destoryItem.
Here's what I have (I'm probably missing stuff):
In my Fragment, I am getting the entire fragment layout, and then the ViewPager item from within it, setting the Adapter, the id (not sure if this is needed or what it does), and setting the currentItem.
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_how_to_play, parent, false);
HowToPlayPagerAdapter adapter = new HowToPlayPagerAdapter(getActivity());
ViewPager viewPager = (ViewPager) v.findViewById(R.id.how_to_play_view_pager);
viewPager.setAdapter(adapter);
viewPager.setId(R.id.viewPager);
viewPager.setCurrentItem(0);
return v;
}
Still in this Class I have my PagerAdapter, this is where I know there are problems as I am not sure how exactly to implement this.
class HowToPlayPagerAdapter extends PagerAdapter {
private Activity parent;
public HowToPlayPagerAdapter(Activity parent) {
this.parent = parent;
}
public Object instantiateItem(View collection, int position) {
// TODO: In here I think we'll want to really get the same view every time and just fill it in properly
return parent.findViewById(R.id.how_to_play_view_pager_id);
}
#Override
public int getCount() {
return mHowToPlayPages.size();
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
#Override
public void destroyItem(View container, int position, Object object) {
super.destroyItem(container, position, object);// No idea what to do in here
}
}
This is my fragment layout where the ViewPager is actually defined.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/top_header_background_shadowed"
android:orientation="horizontal"
android:paddingBottom="8dp"
android:paddingLeft="16dp"
android:paddingTop="8dp" >
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/ic_launcher" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/logo_need2buythis" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="#+id/how_to_play_view_pager" />
</LinearLayout>
And this is the layout for the View I'd like to be inside the ViewPager and then I would fill in the TextView and other elements I'm yet to add depending on which position we're at in the Pager.
<?xml version="1.0" encoding="utf-8"?>
<TextView
android:id="#+id/how_to_play_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="32dp"
android:text="Gameplay" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
Currently when I run it I do see the fragment layout but I see nothing where the ViewPager content should be (no surprise there because I'm not filling in anything with the Text in my current implementation because I don't know where/how to), and when I start just swiping back and forth for a while my app eventually crashes saying I did not override destroyItem.

How to set a fixed size imageView embedded in the fragment?

I made a listfragment to show the imageview embedded in another fragment.
By choosing the items of the list, different images with different resolution will be shown.
But I want to make them to be shown as the same size.So this is what I did.
But with different images and resolutions, they are shown in different sizes.
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/myImageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="fitXY"
android:contentDescription="#string/description"
android:background="#FFF"
android:padding="10dp"
>
</ImageView>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment android:name="com.example.showdognames.DogImageFragment"
android:id="#+id/DogImageFragment"
android:layout_weight="wrap_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<fragment android:name="com.example.showdognames.DognameFragment"
android:id="#+id/DognameFragment"
android:layout_weight="wrap_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
public class DogImageFragment extends Fragment {
Integer[] imageList = new Integer[] { R.drawable.alaskan_malamute,
R.drawable.beagle, R.drawable.border_terrier, R.drawable.dashshund,
R.drawable.finnish_spitz, R.drawable.greyhound,
R.drawable.portuguese_water_dog, R.drawable.rottweiler };
private ImageView myView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myView = (ImageView) inflater.inflate(R.layout.dog_image_fragment,
container, false);
myView.setLayoutParams(new LinearLayout.LayoutParams(200,200));
return myView;
}
// method setImageResource is used to bound image reference array and
// imageView
public void update(int position) {
if (myView != null) {
myView.setImageResource(imageList[position]);
}
}
}
android:layout_weight="wrap_content"
Seriously?
If the problem is the ImageView that not shows the image at the desired width and height you can set the android:scaleType of imageview try with fitCenter or fitXY. and see what you want to show.

Categories

Resources