I am trying to get the bitmap of my mImageView in a Fragment class.
I notices that I can see the correct drawables, but bitmap is only created sometimes, while most often is Null.
Here is the code:
package com.example.android.displayingbitmaps.ui;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.android.displayingbitmaps.R;
import com.example.android.displayingbitmaps.util.ImageFetcher;
import com.example.android.displayingbitmaps.util.ImageWorker;
import com.example.android.displayingbitmaps.util.Utils;
/**
* This fragment will populate the children of the ViewPager from {#link ImageDetailActivity}.
*/
public class ImageDetailFragment extends Fragment {
private static final String IMAGE_DATA_EXTRA = "extra_image_data";
private String mImageUrl;
private ImageView mImageView;
private ImageFetcher mImageFetcher;
/**
* Factory method to generate a new instance of the fragment given an image number.
*
* #param imageUrl The image url to load
* #return A new instance of ImageDetailFragment with imageNum extras
*/
public static ImageDetailFragment newInstance(String imageUrl) {
final ImageDetailFragment f = new ImageDetailFragment();
final Bundle args = new Bundle();
args.putString(IMAGE_DATA_EXTRA, imageUrl);
f.setArguments(args);
return f;
}
/**
* Empty constructor as per the Fragment documentation
*/
public ImageDetailFragment() {}
/**
* Populate image using a url from extras, use the convenience factory method
* {#link ImageDetailFragment#newInstance(String)} to create this fragment.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mImageUrl = getArguments() != null ? getArguments().getString(IMAGE_DATA_EXTRA) : null;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate and locate the main ImageView
final View v = inflater.inflate(R.layout.image_detail_fragment, container, false);
mImageView = (ImageView) v.findViewById(R.id.imageView);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Use the parent activity to load the image asynchronously into the ImageView (so a single
// cache can be used over all pages in the ViewPager
if (ImageDetailActivity.class.isInstance(getActivity())) {
mImageFetcher = ((ImageDetailActivity) getActivity()).getImageFetcher();
mImageFetcher.loadImage(mImageUrl, mImageView);
BitmapDrawable drawable = (BitmapDrawable) mImageView.getDrawable();
Bitmap bitmap = drawable.getBitmap();
Toast.makeText(getActivity(), "Drawable is: "+drawable,Toast.LENGTH_SHORT).show(); }
// Pass clicks on the ImageView to the parent activity to handle
if (OnClickListener.class.isInstance(getActivity()) && Utils.hasHoneycomb()) {
mImageView.setOnClickListener((OnClickListener) getActivity());
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (mImageView != null) {
// Cancel any pending image work
ImageWorker.cancelWork(mImageView);
mImageView.setImageDrawable(null);
}
}
}
FragmentActivity class
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager.LayoutParams;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.android.displayingbitmaps.BuildConfig;
import com.example.android.displayingbitmaps.R;
import com.example.android.displayingbitmaps.provider.Images;
import com.example.android.displayingbitmaps.util.ImageCache;
import com.example.android.displayingbitmaps.util.ImageFetcher;
import com.example.android.displayingbitmaps.util.Utils;
public class ImageDetailActivity extends FragmentActivity implements OnClickListener {
private static final String IMAGE_CACHE_DIR = "images";
public static final String EXTRA_IMAGE = "extra_image";
private ImagePagerAdapter mAdapter;
private ImageFetcher mImageFetcher;
private ViewPager mPager;
private ImageView mImageView;
#TargetApi(VERSION_CODES.HONEYCOMB)
#Override
public void onCreate(Bundle savedInstanceState) {
if (BuildConfig.DEBUG) {
Utils.enableStrictMode();
}
super.onCreate(savedInstanceState);
setContentView(R.layout.image_detail_pager);
// Fetch screen height and width, to use as our max size when loading images as this
// activity runs full screen
final DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
final int height = displayMetrics.heightPixels;
final int width = displayMetrics.widthPixels;
// For this sample we'll use half of the longest width to resize our images. As the
// image scaling ensures the image is larger than this, we should be left with a
// resolution that is appropriate for both portrait and landscape. For best image quality
// we shouldn't divide by 2, but this will use more memory and require a larger memory
// cache.
final int longest = (height > width ? height : width) / 2;
ImageCache.ImageCacheParams cacheParams =
new ImageCache.ImageCacheParams(this, IMAGE_CACHE_DIR);
cacheParams.setMemCacheSizePercent(0.25f); // Set memory cache to 25% of app memory
// The ImageFetcher takes care of loading images into our ImageView children asynchronously
mImageFetcher = new ImageFetcher(this, longest);
mImageFetcher.addImageCache(getSupportFragmentManager(), cacheParams);
mImageFetcher.setImageFadeIn(false);
// Set up ViewPager and backing adapter
mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), Images.imageUrls.length);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setPageMargin((int) getResources().getDimension(R.dimen.horizontal_page_margin));
mPager.setOffscreenPageLimit(2);
// Set up activity to go full screen
getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN);
// Enable some additional newer visibility and ActionBar features to create a more
// immersive photo viewing experience
if (Utils.hasHoneycomb()) {
final ActionBar actionBar = getActionBar();
// Hide title text and set home as up
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
// Hide and show the ActionBar as the visibility changes
mPager.setOnSystemUiVisibilityChangeListener(
new View.OnSystemUiVisibilityChangeListener() {
#Override
public void onSystemUiVisibilityChange(int vis) {
if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
actionBar.hide();
} else {
actionBar.show();
}
}
});
// Start low profile mode and hide ActionBar
mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
actionBar.hide();
}
// Set the current item based on the extra passed in to this activity
final int extraCurrentItem = getIntent().getIntExtra(EXTRA_IMAGE, -1);
if (extraCurrentItem != -1) {
mPager.setCurrentItem(extraCurrentItem);
}
}
#Override
public void onResume() {
super.onResume();
mImageFetcher.setExitTasksEarly(false);
}
#Override
protected void onPause() {
super.onPause();
mImageFetcher.setExitTasksEarly(true);
mImageFetcher.flushCache();
}
#Override
protected void onDestroy() {
super.onDestroy();
mImageFetcher.closeCache();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
case R.id.clear_cache:
mImageFetcher.clearCache();
Toast.makeText(
this, R.string.clear_cache_complete_toast,Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
/**
* Called by the ViewPager child fragments to load images via the one ImageFetcher
*/
public ImageFetcher getImageFetcher() {
return mImageFetcher;
}
/**
* The main adapter that backs the ViewPager. A subclass of FragmentStatePagerAdapter as there
* could be a large number of items in the ViewPager and we don't want to retain them all in
* memory at once but create/destroy them on the fly.
*/
private class ImagePagerAdapter extends FragmentStatePagerAdapter {
private final int mSize;
public ImagePagerAdapter(FragmentManager fm, int size) {
super(fm);
mSize = size;
}
#Override
public int getCount() {
return mSize;
}
#Override
public Fragment getItem(int position) {
return ImageDetailFragment.newInstance(Images.imageUrls[position]);
}
}
/**
* Set on the ImageView in the ViewPager children fragments, to enable/disable low profile mode
* when the ImageView is touched.
*/
#TargetApi(VERSION_CODES.HONEYCOMB)
#Override
public void onClick(View v) {
final int vis = mPager.getSystemUiVisibility();
//Toast.makeText(this, "Value is: " + ,Toast.LENGTH_SHORT).show();
if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
} else {
mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
}
}
}
As you can see I put a Toast that show me this:
When Toast is Drawable:
When Toast is Bitmap, shows bitmap null sometimes for same image (as I swipe back and forward through the gallery):
Bitmap not null on same image:
I am using an AVD image of Android M 6.0
Related
I'm currently working in my own project of dental application, i would like to ask if how to pass a certain data from a custom dialog and show or add it to the target fragment?
Appreciate for any help.
This is the Custom Dialog Screenshot:
CustomDialog.java
package com.bloxofcode.multipletabs;
import android.app.Activity;
import android.app.Dialog;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.bloxofcode.multipletabs.Tab1;
public class CustomDialog extends Dialog implements
View.OnClickListener {
public Activity c;
public CustomDialog d;
public Button yes, no;
ToggleButton btnGenderMale,btnGenderFemale;
Button btnCancel, btnAccept;
EditText eText;
public CustomDialog(Activity a) {
super(a);
// TODO Auto-generated constructor stub
this.c = a;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setBackgroundDrawableResource(android.R.drawable.dialog_holo_light_frame);
}
else{
getWindow().setBackgroundDrawableResource(android.R.drawable.alert_light_frame);
}
setContentView(R.layout.activity_dialog);
btnGenderFemale = (ToggleButton) findViewById(R.id.toggleButtonFemale);
btnGenderMale = (ToggleButton) findViewById(R.id.toggleButtonMale);
btnCancel = (Button) findViewById(R.id.btnCancel);
btnAccept = (Button) findViewById(R.id.btnAccept);
eText = (EditText) findViewById(R.id.editText);
btnGenderMale.setChecked(true);
btnGenderMale.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonMale, boolean b) {
// Toast.makeText(getApplicationContext(),
// String.valueOf(buttonMale.isChecked()), Toast.LENGTH_SHORT).show();
if(buttonMale.isChecked()){
btnGenderMale.setEnabled(false);
btnGenderFemale.setEnabled(true);
btnGenderFemale.setChecked(false);
}else{
}
}
});
btnGenderFemale.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonFemale, boolean b) {
// Toast.makeText(getApplicationContext(),
// String.valueOf(buttonFemale.isChecked()), Toast.LENGTH_SHORT).show();
if(buttonFemale.isChecked()){
btnGenderMale.setEnabled(true);
btnGenderFemale.setEnabled(false);
btnGenderMale.setChecked(false);
}else{
}
}
});
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dismiss();
}
});
btnAccept.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getContext(),"Sample",Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onClick(View v) {
dismiss();
}
}
How to achieve this Expected Result:
Tab1.java
package com.bloxofcode.multipletabs;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v4.app.Fragment;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ListView;
import com.bloxofcode.multipletabs.database.DBOpenHelper;
import com.bloxofcode.multipletabs.database.NotesProvider;
/**
* A simple {#link Fragment} subclass.
*/
public class Tab1 extends Fragment {
private ImageButton imgButton;
private CustomDialog customDialog;
View v;
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v =inflater.inflate(R.layout.tab_1,container,false);
imgButton = (ImageButton) v.findViewById(R.id.imageButton);
//Creating ImageButton
imgButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Toast.makeText(getActivity(),"Hello Image Button!",Toast.LENGTH_LONG).show();
customDialog = new CustomDialog(getActivity());
customDialog.show();
}
});
press();
return v;
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public void press() {
insertNote("Juan Dela Cruz");
Cursor cursor = getActivity().getContentResolver().query(NotesProvider.CONTENT_URI,
DBOpenHelper.ALL_COLUMNS, null, null, null, null);
String[] from = {DBOpenHelper.NOTE_TEXT};
int[] to = {android.R.id.text1};
CursorAdapter cursorAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1,cursor,from,to,0);
ListView list = (ListView) v.findViewById(android.R.id.list);
list.setAdapter(cursorAdapter);
}
private void insertNote(String noteText) {
ContentValues values = new ContentValues();
values.put(DBOpenHelper.NOTE_TEXT,noteText);
Uri noteUri =getActivity().getContentResolver().insert(NotesProvider.CONTENT_URI,values);
Log.d("MainActivity","Inserted note " + noteUri.getLastPathSegment());
}
}
ViewPagerAdapter.java
package com.bloxofcode.multipletabs;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
public class ViewPagerAdapter extends FragmentStatePagerAdapter{
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
// Build a Constructor and assign the passed Values to appropriate values in the class
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
if(position == 0) // if the position is 0 we are returning the First tab
{
Tab1 tab1 = new Tab1();
return tab1;
}
else if(position == 1)
{
Tab2 tab2 = new Tab2();
return tab2;
}
else // As we are having 3 tabs if the position is now 0 it must be 1 so we are returning second tab
{
Tab3 tab3 = new Tab3();
return tab3;
}
}
// This method return the titles for the Tabs in the Tab Strip
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return NumbOfTabs;
}
}
TabsActivity.java
package com.bloxofcode.multipletabs;
import android.os.Build;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class TabsActivity extends AppCompatActivity {
// Declaring Your View and Variables
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"Patient","Appointment","Backup"};
int Numboftabs =3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs);
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
//return ContextCompat.getColor(TabsActivity.this,R.color.tabsScrollColor);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return getResources().getColor(R.color.tabsScrollColor,TabsActivity.this.getTheme());
}else {
return getResources().getColor(R.color.tabsScrollColor);
}
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
}
#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_main, 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_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
If you'd like to keep things loosely coupled and structured, A fine rather alternative is to choose the EventBus . To see the usage see this Answer.
You can accomplish it using Interface.
YourInterface.java
public interface YourInterface{
void yourMethod(int data);
}
Use that Interface in your Dialog class:
public class CustomDialog extends Dialog implements
View.OnClickListener {
private YourInterface delegate;
....
public CustomDialog(Activity a) {
super(a);
// TODO Auto-generated constructor stub
this.c = a;
delegate = (YourInterface) a;
}
}
In your Activity that holds fragment implement interface:
public class YourActivity extends AppCompatActivity implements YourInterface {
....
#Override
public void yourMethod(int data) {
fragment.receiverMethod(data);
}
}
Tab1.java
public class Tab1 extends Fragment {
public void receiverMethod(int data) {
// do what you want with received data
}
}
Now to use that simply call delegate.yourMethod(data) to pass it to fragment
You can use Broadcast Receiver in your onDismiss like below in your Dialog
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (onDismissListener != null) {
Intent intent = new Intent("DialogDismiss");
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
onDismissListener.onDismiss(dialog);
}
}
and in your Fragment you can receive the broadcast
// In your Fragment do below
BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Work Here
}
};
//In OnCreate
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mReceiver,
new IntentFilter("DialogDismiss"));
//onDestroy
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mReceiver);
If you get the view from the customDialog you can just access the fields normally with view.findViewById() from in your fragment class.
Put your data into budle as key-value pair and set bundle as an argument to fragment.
fragment.setArgument(bundle)
To get bundle in fragmen, call
Bundle bundle = getArgument() and get values from the bundle based on key.
You could return the String which was entered into the EditText by creating a setter and getter method within your Dialog class to return a String variable (e.g. editTextString) which you would assign a value to whenever the accept button is clicked.
Add your getter and setter methods to the Dialog class
private void setEditTextString() {
editTextString = eText.getText().toString()
}
public String getEditTextString() {
return editTextString;
}
Within your click listener for the accept button add the following line of code:
setEditTextString(eText.getText().toString());
Then all you need to do to return the value entered in the editText field in the Fragment class would be to call the public method within your Dialog class to return the string.
dialogClass.getEditTextValue()
I have fragment view pager in activity, that creates a number of pages of entered number before. In each fragment, i have recycler view that needs to update each time user moves to the relevant page. on resume() of each fragment I have getter of data from main activity.
What I am experiencing is while I'm going to next page first time it's not updated, but if after some page movements I would back to it, it is updated, with same resume() code.
I tried some delays after updating the data, it didn't help.
So if before updating data I would check every page it would work as I planned, but if the page was not created before (due to pager adapter) but I still use the same code for updating, it does not work.
I would be glad for some help, stacked on it for 2 days already.
Main Activity:
package com.slavafleer.tipcalculator02;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import com.slavafleer.tipcalculator02.recycler.PageHeaderAdapter;
import java.util.ArrayList;
public class ManualModeActivity extends AppCompatActivity implements
PageHeaderAdapter.Callbacks, DinerFragment.Callbacks {
private int mDinersAmount;
private ViewPager mViewPagerDiners;
private PageHeaderAdapter mHeaderAdapter;
private DinersPagerAdapter mDinersPagerAdapter;
private ArrayList<Order> mOrders;
public ArrayList<Order> getOrders() {
return mOrders;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manual_mode);
mOrders = new ArrayList<>();
// Get diners amount from previous activity
Intent intent = getIntent();
mDinersAmount = intent.getIntExtra(Constants.KEY_DINNERS_AMOUNT, 1);
// Initialise PageHeader Recycler
mHeaderAdapter = new PageHeaderAdapter(this, mDinersAmount, this);
final RecyclerView recyclerPageHeader = (RecyclerView) findViewById(R.id.recyclerViewPagerHeader);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerPageHeader.setLayoutManager(linearLayoutManager);
recyclerPageHeader.setAdapter(mHeaderAdapter);
// Initialise ViewPager
mViewPagerDiners = (ViewPager) findViewById(R.id.viewPagerDiners);
FragmentManager fragmentManager = getSupportFragmentManager();
mDinersPagerAdapter = new DinersPagerAdapter(fragmentManager, mDinersAmount);
mViewPagerDiners.setAdapter(mDinersPagerAdapter);
// ViewPager Listener - synchronise with headers recycler
mViewPagerDiners.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
// Gets position for selected page
#Override
public void onPageSelected(int position) {
mHeaderAdapter.selectItem(position);
linearLayoutManager.smoothScrollToPosition(recyclerPageHeader, null,position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
// HeaderPage Adapter Callbacks
// Scroll ViewPager by clicked Header
#Override
public void onItemClick(int position) {
mViewPagerDiners.setCurrentItem(position, true);
}
// DinerFragment.OrderDialog.Callbacks
// Send data to PagerAdapter that would sent to each fragment
#Override
public void onDialogAddClick(Order order) {
Log.d("test", "onDialogAddClick");
mOrders.add(order);
mDinersPagerAdapter.updateOrders();
}
}
PagerAdapter
package com.slavafleer.tipcalculator02;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.ArrayList;
/**
* PagerAdapter for ManualModeActivity ViewPager
*/
public class DinersPagerAdapter extends FragmentPagerAdapter {
private int mDinersAmount;
private ArrayList<DinerFragment> mDinerFragments;
public DinersPagerAdapter(FragmentManager fm, int dinersAmount) {
super(fm);
mDinersAmount = dinersAmount;
mDinerFragments = new ArrayList<>();
}
#Override
public Fragment getItem(int position) {
// Insert diners amount to fragment
Bundle bundle = new Bundle();
bundle.putInt(Constants.KEY_DINNERS_AMOUNT, mDinersAmount);
bundle.putInt(Constants.KEY_CURRENT_PAGE, position);
DinerFragment dinerFragment = new DinerFragment();
dinerFragment.setArguments(bundle);
mDinerFragments.add(dinerFragment); // save fragments references
return dinerFragment;
}
// Diners amount + All
#Override
public int getCount() {
return mDinersAmount + 1;
}
// Update order list in each fragment of view pager
public void updateOrders() {
for(DinerFragment dinerFragment : mDinerFragments) {
dinerFragment.onResume();
}
}
}
Fragment
package com.slavafleer.tipcalculator02;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.slavafleer.tipcalculator02.recycler.OrdersAdapter;
import java.util.ArrayList;
/**
* Diner Fragment Class
*/
public class DinerFragment extends Fragment implements OrderDialog.Callbacks {
private ArrayList<Order> mOrders = new ArrayList<>();
private RecyclerView mRecyclerViewOrders;
private ImageView mImageViewAddOrderButton;
private int mDinersAmount;
private OrdersAdapter mOrdersAdapter;
private int mDinerId;
private Callbacks mCallbacks;
public DinerFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("test", "onCreateView");
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_diner, container, false);
mCallbacks = (Callbacks) inflater.getContext();
// Get Diners Amount
final Bundle bundle = getArguments();
if(bundle != null) {
mDinersAmount = bundle.getInt(Constants.KEY_DINNERS_AMOUNT);
mDinerId = bundle.getInt(Constants.KEY_CURRENT_PAGE);
Log.d("test", "onCreateView " + mDinerId);
}
mRecyclerViewOrders = (RecyclerView) view.findViewById(R.id.recyclerViewOrders);
mOrdersAdapter = new OrdersAdapter(getActivity(), mOrders);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerViewOrders.setLayoutManager(linearLayoutManager);
mRecyclerViewOrders.setAdapter(mOrdersAdapter);
// Due to the bug, we could use just listener and not OnClick in Fragment
mImageViewAddOrderButton = (ImageView) view.findViewById(R.id.imageViewAddButton);
mImageViewAddOrderButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ArrayList<Integer> currentPage = new ArrayList<>();
currentPage.add(mDinerId);
OrderDialog orderDialog = new OrderDialog(getActivity(),
mDinersAmount, currentPage, DinerFragment.this);
orderDialog.show();
}
});
return view;
}
#Override
public void onResume() {
super.onResume();
Log.d("test", "onResume " + mDinerId);
ManualModeActivity activity = (ManualModeActivity) getActivity();
mOrders = activity.getOrders();
for(Order order : mOrders) {
Log.d("test", order.getPrice() + "");
}
int size = mOrders.size();
mOrdersAdapter.notifyDataSetChanged();
mRecyclerViewOrders.smoothScrollToPosition(size);
}
// Blank OrderDialog.Callbacks
// used due to Implements for creation OrderDialog
#Override
public void onDialogAddClick(Order order) {
mCallbacks.onDialogAddClick(order);
}
public interface Callbacks {
void onDialogAddClick(Order order);
}
}
Instead of using onResume use the onPageSelected method and used the passed fragment for context to call the updating method in the fragment.
Finally what I did is replacing mOrdersAdapter.notifyDataSetChanged() on recreating the adapter. I understand that is not a very smart solution but visually it does work as I needed.
I would not mark it as answer cause I still want to know why it acts like I wrote before.
Thanks again.
// mOrdersAdapter.notifyDataSetChanged();
mOrdersAdapter = new OrdersAdapter(getActivity(), mOrders);
mRecyclerViewOrders.setAdapter(mOrdersAdapter);
ViewPager adapter creates 2 fragments at the same time. for instance when you're on page 0, it also creates page 1(lifecycle for page 1: OnCreate->OnCreateView->OnResume->OnPause->OnResume).When you swipe to page 1 only method that is being called is SetMenuVisibility. So in order to update data for page 1 is to call setMenuVisibilty inside of Fragment:
#Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
if(menuVisible && isResumed()){
settingAdapter();
}
}
So here inside of settingAdapter i reloaded data.
so far,it's the best trick i made toward fragments with recyclerviews inside viewpager. But still there are few milliseconds delay for populating fragment with new data)))
I hope this will help you
First of all, I hope my question is clear. If it isn't please comment i will try to make it better!.
i have a question related to putting a item in a arraylist. I am using the master/detail flow (a standard project option in android studio) as a bases for my app. I already modified it but below is de code from the original template to simplify my question. For my problem i think there are three activities involved. Main activity, detail activity, mysavedbooks and the fragment activity.
My Problem
In the detail activity there is a fab button. WHat i want to do is to save the current displayed item in a new arraylist called Saveditems in the activity mysavedbooks.
How can i read the item (which is currently displayed by the detailactivity which extends the fragment) and put this in a saveditems arraylist.
Greetings,
Matthijs
below is the main activity
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import matthijs.bookshelf.dummy.DummyContent;
import java.util.List;
/**
* An activity representing a list of books. This activity
* has different presentations for handset and tablet-size devices. On
* handsets, the activity presents a list of items, which when touched,
* lead to a {#link bookDetailActivity} representing
* item details. On tablets, the activity presents the list of items and
* item details side-by-side using two vertical panes.
*/
public class bookListActivity extends AppCompatActivity {
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device.
*/
private boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle(getTitle());
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
View recyclerView = findViewById(R.id.book_list);
assert recyclerView != null;
setupRecyclerView((RecyclerView) recyclerView);
if (findViewById(R.id.book_detail_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-w900dp).
// If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
}
}
private void setupRecyclerView(#NonNull RecyclerView recyclerView) {
recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(DummyContent.ITEMS));
}
public class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final List<DummyContent.DummyItem> mValues;
public SimpleItemRecyclerViewAdapter(List<DummyContent.DummyItem> items) {
mValues = items;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.book_list_content, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).id);
holder.mContentView.setText(mValues.get(position).content);
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(bookDetailFragment.ARG_ITEM_ID, holder.mItem.id);
bookDetailFragment fragment = new bookDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.book_detail_container, fragment)
.commit();
} else {
Context context = v.getContext();
Intent intent = new Intent(context, bookDetailActivity.class);
intent.putExtra(bookDetailFragment.ARG_ITEM_ID, holder.mItem.id);
context.startActivity(intent);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public DummyContent.DummyItem mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
}
below is the detail activity.
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
/**
* An activity representing a single book detail screen. This
* activity is only used narrow width devices. On tablet-size devices,
* item details are presented side-by-side with a list of items
* in a {#link bookListActivity}.
*/
public class bookDetailActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "saved book", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
// Show the Up button in the action bar.
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
// savedInstanceState is non-null when there is fragment state
// saved from previous configurations of this activity
// (e.g. when rotating the screen from portrait to landscape).
// In this case, the fragment will automatically be re-added
// to its container so we don't need to manually add it.
// For more information, see the Fragments API guide at:
//
// http://developer.android.com/guide/components/fragments.html
//
if (savedInstanceState == null) {
// Create the detail fragment and add it to the activity
// using a fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(bookDetailFragment.ARG_ITEM_ID,
getIntent().getStringExtra(bookDetailFragment.ARG_ITEM_ID));
bookDetailFragment fragment = new bookDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.book_detail_container, fragment)
.commit();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpTo(this, new Intent(this, bookListActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
below is the fragment
package matthijs.bookshelf;
import android.app.Activity;
import android.support.design.widget.CollapsingToolbarLayout;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import matthijs.bookshelf.dummy.DummyContent;
/**
* A fragment representing a single book detail screen.
* This fragment is either contained in a {#link bookListActivity}
* in two-pane mode (on tablets) or a {#link bookDetailActivity}
* on handsets.
*/
public class bookDetailFragment extends Fragment {
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_ITEM_ID = "item_id";
/**
* The dummy content this fragment is presenting.
*/
private DummyContent.DummyItem mItem;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public bookDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
// Load the dummy content specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load content from a content provider.
mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
Activity activity = this.getActivity();
CollapsingToolbarLayout appBarLayout = (CollapsingToolbarLayout) activity.findViewById(R.id.toolbar_layout);
if (appBarLayout != null) {
appBarLayout.setTitle(mItem.content);
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.book_detail, container, false);
// Show the dummy content as text in a TextView.
if (mItem != null) {
((TextView) rootView.findViewById(R.id.book_detail)).setText(mItem.details);
}
return rootView;
}
}
Mysavedbooks activity
package matthijs.tuinierv2;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Matthijs on 12-2-2016.
*/
public class Mysavedbooks {
public static final List<DummyContent.DummyItem> SavedItems= new ArrayList<DummyContent.DummyItem>();
}
I kind of solved to problem for now, except for the twopane mode. I need to look in the solution for the twopane mode further. I think it can be done in a better way but here is the solution.
Please comment if you have a better solution.
I added the String in ItemDetailActivity
public static String SAVED_ITEM_ID;
In the bookListActivity i added a line of code in this part:
` #Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).id);
holder.mContentView.setText(mValues.get(position).content);
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(bookDetailFragment.ARG_ITEM_ID, holder.mItem.id);
bookDetailFragment fragment = new bookDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.book_detail_container, fragment)
.commit();
} else {
Context context = v.getContext();
Intent intent = new Intent(context, bookDetailActivity.class);
intent.putExtra(bookDetailFragment.ARG_ITEM_ID, holder.mItem.id);
//THE line of code I ADDED
itemDetailActivity.SAVED_ITEM_ID = holder.mItem.id;
context.startActivity(intent);
}
}
});
}`
Here is the code i added in the bookDetailActivity to retrieve the current book which is displayed in the itemdetailactivity en thereby the fragment.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fabdetail);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//code i added to retrieve the current item and save it in
int SAVED_ITEM_ID_INT = Integer.parseInt(SAVED_ITEM_ID);
ItemListActivity.PlantItem SAVED_ITEM = ItemListActivity.ITEMS.get(SAVED_ITEM_ID_INT);
Mysavedbooks.SavedItems.add(SAVED_ITEM);
Snackbar.make(view,"Book saved to My books", Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
});
In my actvity I have a viewPager with for example 3 pages.
In all of theses pages, I have a YouTubePlayer with a different id video.
The problem is that all the YouTubePlayer component has the same video at the same time.
Concretely :
When the first page is displayed, the YouTubePlayer show the first video, so all seems to be ok.
When I try to scroll to the 2nd page, I can see that the 2nd YouTubePlayer show the same video.
When the 2nd page is completely displayed (After scrolling), behind the view pager prepare the 3rd page. So on the 3rd page the 3rd id video is set to the YouTubePlayer component. At that moment the 2nd page currently displayed switch automatically to the 3rd video.
It was like if the instance of YouTubePlayer was single for all the pages.
But on each page new FragmentYouTubePlayer() is correctly called.
I don't understand where is the problem.
Finally, I wonder if it's possible to use severals YouTubePlayer component (in a viewpager) at the same time or not ?
Thanks for your help.
I don't remember exactly what was wrong, but yes, I solved my problem. So, if it can help you, here is the code :
In my main activity, using PagerAdapter :
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
fragmentYouTubeContent = FragmentYouTubeContent.create(position);
return fragmentYouTubeContent;
}
#Override
public int getCount() {
int nb = 3;
return nb;
}
}
My FragmentYouTubeContent.class
package com.orange.OrangeJobs;
import java.util.List;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubeStandalonePlayer;
import com.google.android.youtube.player.YouTubeThumbnailLoader;
import com.google.android.youtube.player.YouTubeThumbnailView;
import android.support.v4.app.Fragment;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
public class FragmentYouTubeContent extends Fragment implements YouTubeThumbnailView.OnInitializedListener {
public static final int REQ_START_STANDALONE_PLAYER = 101;
private static final int REQ_RESOLVE_SERVICE_MISSING = 2;
private static final int RECOVERY_DIALOG_REQUEST = 1;
/**
* The fragment's page number.
*/
private int mPageNumber;
private String urlYouTube;
private boolean canHideStatusBar = false;
private Dialog errorDialog;
FrameLayout rl;
private YouTubeThumbnailView thumbnailView;
/**
* Factory method for this fragment class. Constructs a new fragment for the given page number.
*/
public static FragmentYouTubeContent create(int pageNumber) {
FragmentYouTubeContent fragment = new FragmentYouTubeContent();
fragment.setPageNumber(pageNumber);
return fragment;
}
public FragmentYouTubeContent() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#SuppressLint("InlinedApi")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setRetainInstance(true);
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.youtube, container, false);
urlYouTube = "YOUR_VIDEO_URL";
if (!"".equals(urlYouTube)) {
thumbnailView = (YouTubeThumbnailView) rootView.findViewById(R.id.youtubethumbnailview);
thumbnailView.initialize(Params.YOUTUBE_KEY, this);
thumbnailView.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
// Launch standalone YoutTube player
Intent intent = null;
intent = YouTubeStandalonePlayer.createVideoIntent(getActivity(), YOUTUBE_KEY, urlYouTube, 0, true, false);
if (intent != null) {
if (canResolveIntent(intent)) {
canHideStatusBar = true;
startActivityForResult(intent, REQ_START_STANDALONE_PLAYER);
} else {
// Could not resolve the intent - must need to install or update the YouTube API service.
YouTubeInitializationResult
.SERVICE_MISSING
.getErrorDialog(getActivity(), REQ_RESOLVE_SERVICE_MISSING).show();
}
}
}});
}
return rootView;
}
#Override
public void onResume() {
super.onResume();
boolean isLandscape = false;
int currentOrientation = getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
isLandscape = true;
}
else {
isLandscape = false;
}
if (canHideStatusBar && this.isVisible() && isLandscape) {
Utils.hideStatusBar(getActivity());
canHideStatusBar = false;
}
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onInitializationSuccess(YouTubeThumbnailView thumbnailView, YouTubeThumbnailLoader thumbnailLoader) {
thumbnailLoader.setVideo(urlYouTube);
}
#Override
public void onInitializationFailure(YouTubeThumbnailView thumbnailView, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
if (errorDialog == null || !errorDialog.isShowing()) {
errorDialog = errorReason.getErrorDialog(getActivity(), RECOVERY_DIALOG_REQUEST);
errorDialog.show();
}
} else {
String errorMessage = String.format(getString(R.string.error_thumbnail_view), errorReason.toString());
Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show();
}
}
// ***** Private methods *************************************************************************************
private boolean canResolveIntent(Intent intent) {
List<ResolveInfo> resolveInfo = getActivity().getPackageManager().queryIntentActivities(intent, 0);
return resolveInfo != null && !resolveInfo.isEmpty();
}
// ***** Properties methods *************************************************************************************
/**
* Returns the page number represented by this fragment object.
*/
public int getPageNumber() {
return mPageNumber;
}
/**
* #param pageNumber the pageNumber to set
*/
public void setPageNumber(int pageNumber) {
this.mPageNumber = pageNumber;
}
/**
* #return the canHideStatusBar
*/
public boolean isCanHideStatusBar() {
return canHideStatusBar;
}
/**
* #param canHideStatusBar the canHideStatusBar to set
*/
public void setCanHideStatusBar(boolean canHideStatusBar) {
this.canHideStatusBar = canHideStatusBar;
}
}
My layout : youtube.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"
android:clipToPadding="false"
android:background="#color/black"
android:scrollbarStyle="outsideOverlay"
android:orientation="horizontal" >
<com.google.android.youtube.player.YouTubeThumbnailView
android:id="#+id/youtubethumbnailview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:contentDescription="#string/empty_string"
android:src="#drawable/ic_media_embed_play"
/>
</RelativeLayout>
I have implemented an Image Gallery using a GridView displaying thumbnails of images and a Fullscreen Activity which will display each of the images in fullscreen mode. The file paths are passed using Intents (putExtra) to the GridView Activity to display different GridViews depending on folder name in SDCARD.Now the problem I have is that I cannot pass those file paths to the Fullscreen Activity in order to view every image separately.
Below are my Classes ;
MainActivity.java
package info.androidhive.imageslider;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private Button btn1, btn2;
Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button) findViewById(R.id.button1);
btn2 = (Button) findViewById(R.id.button2);
setOnClickListeners();
}
public void setOnClickListeners(){
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.button1:
Toast.makeText(getApplicationContext(), "Loading Gridview 1", Toast.LENGTH_LONG).show();
intent = new Intent(MainActivity.this, GridViewActivity.class);
intent.putExtra("folder", "folder1");
startActivity(intent);
break;
case R.id.button2:
Toast.makeText(getApplicationContext(), "Loading Gridview 2", Toast.LENGTH_LONG).show();
intent = new Intent(MainActivity.this, GridViewActivity.class);
intent.putExtra("folder", "folder2");
startActivity(intent);
}
}
#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;
}
}
So in this activity am passing different folder names for each button clicks.
GridViewActivity.java
This class will receive the intent parameters for the folder names and it will list all image thumbnails for that specific folder. Until here everything is fine and I can view the images for each different folder depending on the button clicked.
package info.androidhive.imageslider;
import info.androidhive.imageslider.adapter.GridViewImageAdapter;
import info.androidhive.imageslider.helper.AppConstant;
import info.androidhive.imageslider.helper.Utils;
import java.io.File;
import java.util.ArrayList;
import java.util.Locale;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Display;
import android.view.WindowManager;
import android.widget.GridView;
import android.widget.Toast;
public class GridViewActivity extends Activity {
private Utils utils;
private ArrayList<String> imagePaths = new ArrayList<String>();
private GridViewImageAdapter adapter;
private GridView gridView;
private int columnWidth;
//Utils
private Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view);
gridView = (GridView) findViewById(R.id.grid_view);
//utils = new Utils(this);
mContext = this;
// Initilizing Grid View
InitilizeGridLayout();
// loading all image paths from SD card
imagePaths = getFilePaths();
// Gridview adapter
adapter = new GridViewImageAdapter(GridViewActivity.this, imagePaths,
columnWidth);
// setting grid view adapter
gridView.setAdapter(adapter);
}
private void InitilizeGridLayout() {
Resources r = getResources();
float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
AppConstant.GRID_PADDING, r.getDisplayMetrics());
columnWidth = (int) ((getScreenWidth() - ((AppConstant.NUM_OF_COLUMNS + 1) * padding)) / AppConstant.NUM_OF_COLUMNS);
gridView.setNumColumns(AppConstant.NUM_OF_COLUMNS);
gridView.setColumnWidth(columnWidth);
gridView.setStretchMode(GridView.NO_STRETCH);
gridView.setPadding((int) padding, (int) padding, (int) padding,
(int) padding);
gridView.setHorizontalSpacing((int) padding);
gridView.setVerticalSpacing((int) padding);
}
/*
* Reading file paths from SDCard // Utils
*/
public ArrayList<String> getFilePaths() {
ArrayList<String> filePaths = new ArrayList<String>();
String folder = getIntent().getStringExtra("folder");
File directory = new File(
android.os.Environment.getExternalStorageDirectory()
+ File.separator + folder);
// check for directory
if (directory.isDirectory()) {
// getting list of file paths
File[] listFiles = directory.listFiles();
// Check for count
if (listFiles.length > 0) {
// loop through all files
for (int i = 0; i < listFiles.length; i++) {
// get file path
String filePath = listFiles[i].getAbsolutePath();
// check for supported file extension
if (IsSupportedFile(filePath)) {
// Add image path to array list
filePaths.add(filePath);
}
}
} else {
// image directory is empty
Toast.makeText(
mContext,
folder
+ " is empty. Please load some images in it !",
Toast.LENGTH_LONG).show();
}
} else {
AlertDialog.Builder alert = new AlertDialog.Builder(mContext);
alert.setTitle("Error!");
alert.setMessage(folder
+ " directory path is not valid! Please set the image directory name AppConstant.java class");
alert.setPositiveButton("OK", null);
alert.show();
}
return filePaths;
}
/*
* Check supported file extensions
*
* #returns boolean
*/
private boolean IsSupportedFile(String filePath) {
String ext = filePath.substring((filePath.lastIndexOf(".") + 1),
filePath.length());
if (AppConstant.FILE_EXTN
.contains(ext.toLowerCase(Locale.getDefault())))
return true;
else
return false;
}
/*
* getting screen width
*/
#SuppressLint("NewApi")
public int getScreenWidth() {
int columnWidth;
WindowManager wm = (WindowManager) mContext
.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
final Point point = new Point();
try {
display.getSize(point);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
point.x = display.getWidth();
point.y = display.getHeight();
}
columnWidth = point.x;
return columnWidth;
}
}
Now Once I click on an image thumbnail my (FullScreenView Activity) cannot pickup the folder names so I can display the Image in Fullscreen mode.
FullScreenViewActivity.java
package info.androidhive.imageslider;
import info.androidhive.imageslider.adapter.FullScreenImageAdapter;
//import info.androidhive.imageslider.helper.Utils;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
public class FullScreenViewActivity extends Activity{
private GridViewActivity gv;
private FullScreenImageAdapter adapter;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen_view);
viewPager = (ViewPager) findViewById(R.id.pager);
//utils = new GridViewActivity(getApplicationContext());
Intent i = getIntent();
int position = i.getIntExtra("position", 0);
adapter = new FullScreenImageAdapter(FullScreenViewActivity.this,
gv.getFilePaths());
viewPager.setAdapter(adapter);
// displaying selected image first
viewPager.setCurrentItem(position);
}
}
I want to know how can I receive the file parameters in my FullScreenActivity?
You can use
intent.putStringArrayListExtra("paths", getFilePaths());
when you go from GridViewActivity to FullScreenViewActivity and in onCreate of FullScreenViewActivity you can do
ArrayList<String> paths = getIntent().getStringArrayListExtra("paths");
which will give you the paths of the images