I'm working on an app which uses a ViewPager with two swiping views (first_page.xml and second_page.xml) and has one activity (activity_main.xml).
When in the main activity class I try to access TextView (which is located in the first_page.xml) using findViewById it can't be found.
This is my activity_main.xml
<RelativeLayout 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"
tools:context=".MainActivity" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
This is my first_page.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/someText"
android:text="example"
android:textSize="42sp" >
</TextView>
</LinearLayout>
This is my customPagerAdapter
public class CustomPagerAdapter extends PagerAdapter {
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.first_page;
break;
}
case 1: {
resId = R.layout.second_page;
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;
}
#Override
public int getCount() {
return 2;
}
}
And this is my MainActivity, where I want get the first_page layout, find its TextView called someText, and set a new custom font.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create and set adapter
CustomPagerAdapter adapter = new CustomPagerAdapter();
ViewPager myPager = (ViewPager) findViewById(R.id.pager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
/*
* Here i want to set a new custom font but it seems the someText can't
* be found because the Activity searches for it in the
* layout.activity_main and not in the layout.first_page
*/
TextView textView = (TextView) findViewById(R.id.someText);
Typeface font = Typeface.createFromAsset(getAssets(), "roboto_thin.ttf");
textView.setTypeface(font);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I'm struggling for two days with this problem.
Any suggestions?
The textview is encapsulated in the container of the fragment. If you get a reference to the correct fragment and get a reference to the container you can call findViewById(R.id.someid).
Sample code:
// TODO cast checks
int item = mViewPager.getCurrentItem();
Fragment frag = (Fragment) mPagerAdapter.getItem(item);
View container = frag.getView();
TextView searchTextView = (TextView) container.findViewById(R.id.someid);
Or is your case:
// TODO add null + cast checks
TextView textView = (TextView) ((Fragment)adapter.getItem(0)).getView().findViewById(R.id.someText);
Related
I am having an Application Containing Different Images using ImageView and ViewPager. I want to set the current image shown through ImageView as Wallpaper.
But it only makes the first image as wallpaper and remaining images when I tried to set as wallpaper it makes the mobile screen black (means it makes wallpaper black) it does not set other images from ImageView as Wallpaper.
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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.testimagesbaby.BabyBoys"
tools:showIn="#layout/activity_baby_boys"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.15"
>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/viewPager">
</android.support.v4.view.ViewPager>
</RelativeLayout>
</LinearLayout>
Java File:
public class BabyBoys extends AppCompatActivity {
ViewPager viewPager;
private AlertDialog dialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_baby_boys);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewPager);
ViewPagerAdapter viewPagerAdapter= new ViewPagerAdapter(this);
viewPager.setAdapter(viewPagerAdapter);
}
public static Bitmap viewToBitmap (View view, int width, int height){
Bitmap bitmap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
Canvas canvas= new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_boys_tab, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_setwall) {
setwall(); }
else if (id == R.id.action_save) {
}
return super.onOptionsItemSelected(item);
}
public void setwall()
{
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setBitmap(viewToBitmap(viewPager, viewPager.getWidth(),viewPager.getHeight()));
Toast.makeText(this, "Sucessfully Wallpaper Set", Toast.LENGTH_LONG).show();
} catch (IOException e){
e.printStackTrace();
}
}
}
ViewPagerAdapter File
public class ViewPagerAdapter extends PagerAdapter {
private Context context;
private LayoutInflater layoutInflater;
private Integer [] images= {R.drawable.b1,R.drawable.b2,R.drawable.b3,R.drawable.b4,R.drawable.b5,R.drawable.b6,R.drawable.b7,R.drawable.b8,R.drawable.b9,R.drawable.b10,R.drawable.b11};
public ViewPagerAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return images.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position){
LayoutInflater inflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_layout, null);
ImageView imageView=(ImageView) view.findViewById(R.id.imageView2);
imageView.setImageResource(images[+position]);
ViewPager vp= (ViewPager) container;
vp.addView(view,0);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object){
ViewPager vp= (ViewPager) container;
View view= (View) object;
vp.removeView(view);
}
}
You need to set the current image to the wallpaper manager.
Do the following changes
Define your images[] in BabyBoys activity
Get the current position of the viewPager in setWall function
int currentImagePos = viewPager.getCurrentItem();
Rather than
wallpaperManager.setBitmap(viewToBitmap(viewPager,viewPager.getWidth(),viewPager.getHeight()));
use
myWallpaperManager.setResource(images[currentImagePos]);
I have a SQLite Database with 3 records for example:
1 - Name1 - Do wash
2 - Name2 - Do this
3 - Name3 - Do that
Now I want to start one activity after another (for each record) when user presses a button. The Activity is always the same with other content.
So what is the best way to do this?
My thoughts are following:
- Make a for loop and use StartActivityForResult(...)
- Pass data throug all activities using intent
- Create a temporary table and read data in each activity
- Change only the content of the layout, but don't know how i could do this
So any suggestions on this?
I think for showing same type of view on multiple content you should use fragment with viewpager.
I am just suggesting code to you for viewpager and fragment -
layout for content (pages.xml)-
<RelativeLayout 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"
tools:context=".MainActivity"
android:id="#+id/rel" >
<TextView
android:id="#+id/pageContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
</RelativeLayout>
Main activity content(activity_main.xml) -
<RelativeLayout 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"
tools:context=".MainActivity" >
<RelativeLayout
android:id="#+id/relativeTextview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/header"
android:padding="5dp" >
<android.support.v4.view.ViewPager
android:id="#+id/reviewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
</RelativeLayout>
Pager adapter for setting on viewpager(ViewPagerAdapter.java)-
public class ViewPagerAdapter extends PagerAdapter {
int size;
Activity act;
View layout;
TextView pagecontent;
Button click;
public ViewPagerAdapter(MainActivity mainActivity, int noofsize) {
// TODO Auto-generated constructor stub
size = noofsize;
act = mainActivity;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return size;
}
#Override
public Object instantiateItem(View container, int position) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) act
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layout = inflater.inflate(R.layout.pages, null);
pagecontent = (TextView) layout.findViewById(R.id.pageContent);
int pagenumberTxt=position + 1;
pagecontent.setText("Now your in Page No " +pagenumberTxt );
((ViewPager) container).addView(layout, 0);
return layout;
}
#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;
}
// }
}
Now in main activity((MainActivity.java) -
public class MainActivity extends Activity {
int noofsize = 6;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPagerAdapter adapter = new ViewPagerAdapter(MainActivity.this,
noofsize);
ViewPager myPager = (ViewPager) findViewById(R.id.reviewpager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
and do not forget to mention activity in manufest.xml.
In pages.xml you can add the button on on click of this button you can change the view for next and previous(mPager.setCurrentItem(position)) using listener.
Using activities for this will take a toll on RAM. Use fragments instead.
Answering your original question, as you have cited, make use of the onActivityResult() and as for your concern in this:
-Change only the content of the layout, but don't know how i could do this
Make use of the passed data from intent and handle accordingly.
I am working with ViewPager with Circle Page Indicator.
And I am following this link for sample
Here in below I mentioned my class details.
HelpScreen.java
This Activity had one fragment called HelpScreenFragment.java
public class HelpScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.help_screen);
HelpScreenFragment helpScreenFragment = new HelpScreenFragment();
FragmentTransaction transaction = getFragmentManager()
.beginTransaction().add(R.id.frame_helpscreen_container,
helpScreenFragment);
transaction.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.help_screen, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
help_screen.xml
<RelativeLayout 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"
tools:context="${relativePackage}.${activityClass}" >
<FrameLayout
android:id="#+id/frame_helpscreen_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
SlidePagerAdapter.java
This class extends PagerAdapter and used to inflate the
public class SlidePagerAdapter extends PagerAdapter {
ImageView helpScreenImage;
List<Integer> drawableBitmap;
int gallery_grid_Images[] = { R.drawable.sample1, R.drawable.sample2,
R.drawable.sample3, R.drawable.sample4, R.drawable.sample5, };
private Context mContext;
Activity activity;
public SlidePagerAdapter(Activity mContext) {
super();
this.activity = mContext;
}
#Override
public int getCount() {
return 0;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.viewpager_layout, container,
false);
helpScreenImage = (ImageView) view.findViewById(R.id.helpscreen_image);
helpScreenImage.setImageResource(gallery_grid_Images[position]);
((ViewPager) container).addView(helpScreenImage);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
}
viewpager_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/helpscreen_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
HelpScreenFragment.java
public class HelpScreenFragment extends Fragment {
ViewPager helpScreenPager;
CirclePageIndicator mCirclePageIndicator;
SlidePagerAdapter mSlidePagerAdapter;
Activity activity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = getActivity();
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.helpscreen_fragment, container,
false);
initializeWidgets(view);
mSlidePagerAdapter = new SlidePagerAdapter(activity);
helpScreenPager.setAdapter(mSlidePagerAdapter);
mCirclePageIndicator.setViewPager(helpScreenPager);
return view;
}
private void initializeWidgets(View view) {
helpScreenPager = (ViewPager) view.findViewById(R.id.pager);
mCirclePageIndicator = (CirclePageIndicator) view
.findViewById(R.id.page_indicator);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
And in helpscreen_fragment.xml contains only ViewPager and CirclePageIndicator
helpscreen_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.example.viewpagerdemo"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--
<ViewFlipper
android:id="#+id/helpscreen_flipper"
android:layout_width="match_parent"
android:layout_height="match_parent" /> -->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.viewpagerdemo.CirclePageIndicator
android:id="#+id/page_indicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/view_pager"
android:padding="10dip" />
</FrameLayout>
When executing the project I am getting only blank screen.
What I did wrong? What changes have to made.
Could anybody help on this?
[1]: http://androidopentutorials.com/android-image-slideshow-using-viewpager/
[2]: http://i.stack.imgur.com/pSold.jpg
Here
#Override
public int getCount() {
return 0;
}
Currently getCount method of SlidePagerAdapter retuning 0 so no item is visible in ViewPager. return gallery_grid_Images array size from getCount() :
#Override
public int getCount() {
return gallery_grid_Images.length;
}
I have a fragment which consists of a Button and a TextView. By clicking the button, I need to change the TextView. But I need to create 18 instances of that fragment and set it to a ViewPager. My problem is how to write the button handler. Because I failed to change the corresponding TextView when I click the button. And it always changed the TextView of the same pages, no matter which the current page is.My code is like below:
fragment_first.xml
<FrameLayout 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" tools:context="com.mycompany.redotgolf.FirstFragment">
<RelativeLayout 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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.mycompany.redotgolf.HoleRecord">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/unfilled_red_circle"
android:id="#+id/par_button"
android:layout_below="#+id/par_label"
android:layout_centerHorizontal="true"
android:gravity="center_vertical|center|center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/par"
android:id="#+id/par_label"
android:textSize="40dp"
android:editable="false"
android:gravity="center"
android:layout_below="#+id/flag"
android:layout_centerHorizontal="true" />
</RelativeLayout>
FirstFragme.java
public class FirstFragment extends Fragment implements View.OnClickListener {
// Store instance variables
private String title;
private int page;
public ContentItem contentItem;
public static FirstFragment newInstance(int page, String title,ContentItem contentItem) {
FirstFragment fragmentFirst = new FirstFragment();
fragmentFirst.contentItem=contentItem;
Bundle args = new Bundle();
args.putInt("someInt", page);
args.putString("someTitle", title);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
// Store instance variables based on arguments passed
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
page = getArguments().getInt("someInt", 0);
title = getArguments().getString("someTitle");
}
// Inflate the view for the fragment based on layout XML
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_first, container, false);
v.setId(page);
View tv = v.findViewById(R.id.num_par);
((TextView)tv).setText(contentItem.par.toString());
return v;
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.par_button: {
Integer par;
View view=getView();
TextView textView=(TextView)view.findViewById(R.id.num_par);
if((par=Integer.parseInt(textView.getText().toString()))<5){
par++;
contentItem.par++;
textView.setText(par.toString());
}else{
textView.setText("3");
contentItem.par=3;
}
System.out.println(par);
break;
}
}
}
}
HoleRecord.java
public class HoleRecord extends FragmentActivity {
public FragmentPagerAdapter adapterViewPager;
static ArrayList<ContentItem> contentItems=getSampleContent();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hole_record);
// Retrieve the ViewPager from the content view
ViewPager vp = (ViewPager) findViewById(R.id.viewpager);
// Set an OnPageChangeListener so we are notified when a new item is selected
vp.setOnPageChangeListener(mOnPageChangeListener);
// Finally set the adapter so the ViewPager can display items
adapterViewPager = new MyPagerAdapter(getSupportFragmentManager());
vp.setAdapter(adapterViewPager);
vp.setCurrentItem(1);
adapterViewPager.getItem(1);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_hole_record, menu);
return true;
}
public static class MyPagerAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 18;
//public FirstFragment f;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
FirstFragment f= FirstFragment.newInstance(position, "Page"+position,contentItems.get(position));
return f;
}
// Returns the page title for the top indicator
#Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}
/* private final PagerAdapter mPagerAdapter = new PagerAdapter() {
LayoutInflater mInflater;
#Override
public int getCount() {
//return mItems.size();
return 10;
}
#Override
public boolean isViewFromObject(View view, Object o) {
return view == o;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
// Just remove the view from the ViewPager
container.removeView((View) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
// Ensure that the LayoutInflater is instantiated
if (mInflater == null) {
mInflater =(LayoutInflater) container.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
// Inflate item layout for images
View iv = (View) mInflater.inflate(R.layout.score_par_view, container, false);
// Add the view to the ViewPager
container.addView(iv);
return iv;
}
};*/
/**
* A OnPageChangeListener used to update the ShareActionProvider's share intent when a new item
* is selected in the ViewPager.
*/
private final ViewPager.OnPageChangeListener mOnPageChangeListener
= new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// NO-OP
}
#Override
public void onPageSelected(int position) {
//setShareIntent(position);
}
#Override
public void onPageScrollStateChanged(int state) {
// NO-OP
}
};
static ArrayList<ContentItem> getSampleContent() {
ArrayList<ContentItem> items = new ArrayList<ContentItem>();
for(int i=1;i<=18;i++) {
items.add(new ContentItem(i));
}
return items;
}
}
activity_hole_record.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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.mycompany.redotgolf.HoleRecord">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
In above code, ContentItem class is used to store the value to be presented in the TextView
I am new to Android and am trying a sample application for showing ViewPagers in a Master-Detail Flow using custom PagerAdapters and FragmentStatePagerAdapters. My application has a list of dummy items managed by a SQLiteDatabase which contain a title String, a description String, a Boolean like status, and a list of images (I plan to implement them as downloading from String urls but presently I'm just trying with a single image resource). I am having two problems in the Detail View.
My intention is to use a ViewPager with a FragmentStatePagerAdapter to show the detail view, which consists of a ViewPager with a custom PagerAdapter for showing the list of images, TextView for title and description, a ToggleButton for the like status and a delete button for deleting items from the list.
Issues:
The ViewPager with the custom PagerAdapter does not display the image. It occupies the expected space and swipes performed on it also behave as expected. Only the image is not visible.
[RESOLVED] On using the delete button, I am able to delete the item from the database, and also update the Master View accordingly, but I am not able to update the Detail View, and the app crashes.
Here is my code:
Code that calls ItemDetailActivity.java
#Override
public void onClick(View v) {
Intent detailIntent = new Intent(getContext(), ItemDetailActivity.class);
detailIntent.putExtra(ItemDetailFragment.ARG_LIST_POSITION, holder.position);
getContext().startActivity(detailIntent);
}
ItemDetailActivity.java
public class ItemDetailActivity extends FragmentActivity {
static ItemDetailPagerAdapter idpa;
static ViewPager detailPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
idpa = new ItemDetailPagerAdapter(getSupportFragmentManager());
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
detailPager = (ViewPager) findViewById(R.id.item_detail_container);
detailPager.setAdapter(idpa);
detailPager.setCurrentItem(getIntent().getIntExtra(ItemDetailFragment.ARG_LIST_POSITION, 0));
}
}
activity_item_detail.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/item_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.trial.piclist.ItemDetailActivity"
tools:ignore="MergeRootFrame" />
ItemDetailFragment.java
public class ItemDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
public static final String ARG_LIST_POSITION = "list_index";
public static final String ARG_TWO_PANE = "is_two_pane";
int position = -1;
long id = -1;
boolean twoPane = false;
ViewPager pager;
private PicItem mItem;
public ItemDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
twoPane = getArguments().getBoolean(ARG_TWO_PANE, false);
position = getArguments().getInt(ARG_LIST_POSITION, -1);
id = getArguments().getLong(ARG_ITEM_ID, -1);
if (id == -1)
id = ItemListFragment.getIdByPosition(position);
setmItem(id);
}
public void setmItem(long id) {
if (id >= 0) {
try {
ItemListActivity.lds.open();
mItem = ItemListActivity.lds.getById(id);
ItemListActivity.lds.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
if (mItem != null) {
List<String> pics = new ArrayList<String>();
pics.add("1");
pics.add("2");
pics.add("3");
pics.add("4");
pics.add("5");
mItem.setPics(pics);
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail,
container, false);
DetailViewHolder holder = new DetailViewHolder();
pager = (ViewPager) rootView.findViewById(R.id.pager);
ImagePagerAdapter adapter = new ImagePagerAdapter(mItem, getActivity(),
inflater, position);
pager.setAdapter(adapter);
holder.position = getArguments().getInt(ARG_LIST_POSITION);
holder.ttv = (TextView) rootView.findViewById(R.id.item_title);
holder.dtv = (TextView) rootView.findViewById(R.id.item_detail);
holder.likeButton = (ToggleButton) rootView
.findViewById(R.id.item_like);
holder.deleteButton = (Button) rootView.findViewById(R.id.item_delete);
rootView.setTag(holder);
if (mItem != null) {
holder.ttv.setText(mItem.getTitle());
holder.dtv.setText(mItem.getDescription());
holder.likeButton.setChecked(mItem.getIsLiked());
holder.likeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ItemListActivity.lds.open();
ItemListActivity.lds.toggleLike(mItem.getId());
mItem.toggleIsLiked();
ItemListActivity.lds.close();
ItemListFragment.listDisplayHelper.toggleLiked(position);
}
});
holder.deleteButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ItemListActivity.lds.open();
ItemListActivity.lds.removeItem(mItem.getId());
ItemListActivity.lds.close();
ItemListFragment.listDisplayHelper.remove(position);
ItemListActivity.idpa.notifyDataSetChanged();
// What do I do so that the FragmentStatePagerAdapter is
// updated and the viewpager shows the next item.
}
});
}
return rootView;
}
static private class DetailViewHolder {
TextView ttv;
TextView dtv;
ToggleButton likeButton;
Button deleteButton;
int position;
}
}
fragment_item_detail.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:orientation="vertical"
android:padding="16dp"
tools:context="com.trial.piclist.ItemDetailFragment" >
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="200dip">
</android.support.v4.view.ViewPager>
<TableRow
android:id="#+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/item_title"
style="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello"
android:textIsSelectable="true" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<include
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="#layout/controls_layout" />
</TableRow>
<ScrollView
android:id="#+id/descScrollView"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/item_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello" />
</LinearLayout>
</ScrollView>
</LinearLayout>
controls_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ToggleButton
android:id="#+id/item_like"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_gravity="right"
android:background="#android:drawable/btn_star"
android:gravity="center"
android:text="#string/like_list_item"
android:textOff="#string/empty_text"
android:textOn="#string/empty_text" />
<Button
android:id="#+id/item_delete"
style="?android:attr/buttonStyleSmall"
android:layout_width="30dip"
android:layout_height="30dip"
android:background="#android:drawable/ic_menu_delete"
android:text="#string/empty_text" />
</LinearLayout>
Custom PagerAdapter
ImagePagerAdapter.java
public class ImagePagerAdapter extends PagerAdapter {
LayoutInflater inflater;
List<View> layouts = new ArrayList<>(5);
// Constructors.
#Override
public Object instantiateItem(ViewGroup container, int position) {
if (layouts.get(position) != null) {
return layouts.get(position);
}
View layout = inflater.inflate(R.layout.detail_image,
((ViewPager) container), true);
try {
ImageView loadSpace = (ImageView) layout
.findViewById(R.id.detail_image_view);
loadSpace.setBackgroundColor(0x000000);
loadSpace.setImageResource(R.drawable.light_grey_background);
loadSpace.setAdjustViewBounds(true);
} catch (Exception e) {
System.out.println(e.getMessage());
}
layout.setTag(images.get(position));
layouts.set(position, layout);
return layout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
#Override
public int getCount() {
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (((View) object).findViewById((view.getId())) != null);
}
}
FragmentPagerAdapter
ItemDetailPagerAdapter.java
public class ItemDetailPagerAdapter extends FragmentStatePagerAdapter {
public ItemDetailPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new ItemDetailFragment();
Bundle args = new Bundle();
args.putLong(ItemDetailFragment.ARG_ITEM_ID, ItemListFragment.getIdByPosition(position));
args.putInt(ItemDetailFragment.ARG_LIST_POSITION, position);
args.putBoolean(ItemDetailFragment.ARG_TWO_PANE, ItemListActivity.mTwoPane);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
openDatabase();
int c = database.getCount();
closeDatabase();
return c;
}
#Override
public int getItemPosition(Object object) {
long mId = ((ItemDetailFragment) object).getmId();
int pos = POSITION_NONE;
openDatabase();
if (database.contains(mId)) {
pos = database.getPositionById(mId);
}
closeDatabase();
return pos;
}
}
Any help is much appreciated. Thanks :)
In your ItemDetailFragment, remove the viewpager from the holder, it should be directly into the returned view, something like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail,
container, false);
pager = (ViewPager) rootView.findViewById(R.id.pager);
ImagePagerAdapter adapter = new ImagePagerAdapter(mItem, getActivity(),inflater, position);
pager.setAdapter(adapter);
return rootView;
}
and the ViewHolder pattern should be applied inside your PagerAdapter.
In ImagePagerAdapter.java, correct the isViewFromObject method -
#Override
public boolean isViewFromObject(View view, Object object) {
return (view == (View) object);
}
This will correct the issue of the ImageView.
In ItemDetailPagerAdapter.java, override the getItemPosition method -
#Override
public int getItemPosition(Object object) {
int ret = POSITION_NONE;
long id = ((ItemDetailFragment) object).getId();
openDatabase();
if (databaseContains(id)) {
ret = positionInDatabase(id);
}
closeDatabase();
return ret;
}
On deleting call the FragmentStatePagerAdapter.NotifyDataSetChanged() method. This will make the Adapter update itself on deleting.
Although, the FragmentStatePagerAdapter uses a list of Fragments and of stored states to implement the adapter. That is also causing trouble. To remove that, implement your own list of Fragments.