I have a Fragment (CreaStanzaFragment) with an ImageButton.
This ImageButton has a picture.
Now when I click on this imagebutton, he open a new class (Gallery, an activity with lot of images). When I click on one of this image I need that the ImageButton (In fragment) change and open this fragment with this new picture in imagebutton.
CreaStanzaFragment belongs to a navigationdrawer.
This is Fragment code:
public class CreaStanzaFragment extends Fragment {
public CreaStanzaFragment(){}
ImageButton icon;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_log_creastanza, container, false);
return rootView;
}
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
icon = (ImageButton) view.findViewById(R.id.newicon);
icon.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getContext(), Galleria.class));
}
});
}
here i post only important parts of Galleria
public class Galleria extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gallery_main); //where all the images are located
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
// ......
recyclerView.addOnItemTouchListener(new GalleryAdapter.RecyclerTouchListener(getApplicationContext(), recyclerView, new GalleryAdapter.ClickListener() {
#Override
public void onClick(View view, int position) {
Bundle bundle = new Bundle();
bundle.putSerializable("images", images);
bundle.putInt("position", position);
Image image = images.get(position);
String ilnome = inomi.get(position);
Log.i("ILNOME", ilnome);
// What i need to do here to change pictures of ImageButton? How can i open Fragment?
ImageButton icon = (ImageButton) findViewById(R.id.newicon); //loceted in Fragment (CreaStanzaFragment)
imageButton.setBackgroundResource(0);
Glide.with(getApplicationContext()).load(image.getMedium())
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageButton);
fragmentTransaction.commit();
}
Whit this code:
setContentView(R.layout.activity_log_creastanza);
ImageButton imageButton = (ImageButton) findViewById(R.id.newicon);
imageButton.setBackgroundResource(0);
Glide.with(getApplicationContext()).load(image.getMedium())
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageButton);
When i open CreaStanzaFragment:
When i click on blue picture (open Galleria activity)
When i click on 1 of pictures:
WHY?
Basic Problem is that you need to access your Fragment from the Galleria Instance. For that you can temporarily "pass" the current Fragment to the Galleria.
Galleria Class holding a reference to current CreaStanzaFragment:
public class Galleria extends Activity {
private static CreaStanzaFragment currentCreaStanzaFragment = null;
public static void setFragment(CreaStanzaFragment f) {currentCreaStanzaFragment = f;}
public static CreaStanzaFragment getFragment() {return currentCreaStanzaFragment;}
...
In CreaStamzaFragment you set the Fragment Reference before Intent Action is invoked:
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
icon = (ImageButton) view.findViewById(R.id.newicon);
icon.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
// pass Fragment Reference
Galleria.setFragment(CreaStamzaFragment .this)
startActivity(new Intent(getContext(), Galleria.class));
}
});
}
In Galleria on Adapter Action, access the fragment and modify the imageButton (implies that fragment is still active in background and is not reloaded):
recyclerView.addOnItemTouchListener(new GalleryAdapter.RecyclerTouchListener(getApplicationContext(), recyclerView, new GalleryAdapter.ClickListener() {
#Override
public void onClick(View view, int position) {
Bundle bundle = new Bundle();
bundle.putSerializable("images", images);
bundle.putInt("position", position);
Image image = images.get(position);
String ilnome = inomi.get(position);
Log.i("ILNOME", ilnome);
// get imagebutton on fragment
CreaStamzaFragment f = Galleria.getFragment()
ImageButton icon = (ImageButton) f. getView().findViewById(R.id.newicon); //loceted in Fragment (CreaStanzaFragment)
// load as icon
icon.setBackgroundResource(0);
Glide.with(getApplicationContext()).load(image.getMedium())
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(icon);
// explicit release reference
Galleria.setFragment(null);
// close galliera activity
Galleria.this.finish();
}
...
Note: Be aware that this introduces coupling between the Fragment and Galleria, a cleaner but possibly more complex process would be for example to use a Notification (Observer Pattern) from "Notifier" Galleria to "Listener" Fragment that an Image was selected and the Fragment should load the image instead in the notification handler.
Yet it is fast to implement and sufficient if Galleria/CreaStanzaFragment are not to be reused.
Related
I try to pass data from recyclerview viewholder adapter to another fragment, only i got is text but images do not show, i tries different codes but no image show, it shows blank, image not display. if i use picasso it gives target must not be zero error
my adapter
Picasso.with(context).load(image).fit().into(holder.clothImage);
holder.clothImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Clicked", Toast.LENGTH_SHORT).show();
holder.btn_add_to_cart.setText("Clicked");
GoodDetailFragment detailFragment = new GoodDetailFragment();
AppCompatActivity activity = (AppCompatActivity) v.getContext();
GoodDetailFragment detailFragment1 = new GoodDetailFragment().newInstance(itemList.get(pos).getPrice(), itemList.get(pos).getIcon(), itemList.get(pos).getName());
activity.getSupportFragmentManager()
.beginTransaction()
.replace(R.id.realtabcontent, detailFragment1)
.addToBackStack(null).commit();
}
});
and my next fragment (detail fragment)
*/
public class GoodDetailFragment extends BaseFragment {
private static final String GOOD_PRICE = "";
private static final String GOOD_IMG = "GOOD_IMG";
private static final String GOOD_TITLE = "GOOD_IMG";
#BindView(R.id.dela_img)
DraweeView goodImg;
#BindView(R.id.bei_dela)
TextView delaPrice;
public GoodDetailFragment newInstance(String price, int icon, String title) {
Bundle bundle = new Bundle();
//bundle.putInt(GOOD_IMG, icon);
bundle.putString(GOOD_PRICE, price);
bundle.putString(GOOD_TITLE, title);
bundle.getInt(GOOD_IMG, icon);
GoodDetailFragment detailFragment = new GoodDetailFragment();
detailFragment.setArguments(bundle);
return detailFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO: inflate a fragment view
View rootView = super.onCreateView(inflater, container, savedInstanceState);
ButterKnife.bind(this, rootView);
return rootView;
}
#Override
public View createView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_good_detail, container, false);
ButterKnife.bind(this, view);
return view;
}
#Override
public void init() {
int image = getArguments().getInt(GOOD_IMG);
String price = getArguments().getString(GOOD_PRICE);
String tittle = getArguments().getString(GOOD_TITLE);
Uri uri = Uri.parse(String.valueOf(image));
//Picasso.with(getContext()).load(image).fit().into(goodImg); //GIves Error : Resource ID must not be zero.
delaPrice.setText(price);
Bitmap bitmap = BitmapFactory.decodeFile(String.valueOf(new File(String.valueOf(image))));
// goodImg.setImageBitmap(bitmap); // no image show
goodImg.setImageURI(uri);// still no image show
//Picasso.with(getContext()).load(uri).into(goodImg);// still no image show
if there is way i can get image from recycler view to detail fragment, please help
There are two activities in my app:
MainActivity (containing 3 fragments)
FragmentHome
FragmentOrders
FragmentAccount
AccountEditActivity
The code to set fragments in MainActivity is this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
// set Home as the default fragment
setFragment(FragmentMainHome.getInstance());
}
private void setFragment(Fragment fragment){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, fragment);
transaction.commit();
}
The code for FragmentAccount is:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_activity_main_account, container, false);
layout = rootView.findViewById(R.id.layout_fragment_main_account);
etName = (EditText) layout.findViewById(R.id.etNameLabelValue);
etEmail = (EditText) layout.findViewById(R.id.etEmailLabelValue);
etGender = (EditText) layout.findViewById(R.id.etGenderLabelValue);
etPhoneNumber = (EditText) layout.findViewById(R.id.etPhoneNumberLabelValue);
btnEditAccount = (ImageButton) layout.findViewById(R.id.btnEditAccount);
btnManageAddresses = (ImageButton) layout.findViewById(R.id.btnAccountManageAddresses);
btnManageAddresses.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
btnEditAccount.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return rootView;
}
The code for FragmentOrders is:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_activity_main_order_history, container, false);
layout = rootView.findViewById(R.id.layout_fragment_main_order_history);
lvOrders = (ListView) layout.findViewById(R.id.lvOrders);
tvNoOrdersFound = (TextView) layout.findViewById(R.id.tvNoOrdersFound);
final SwipeRefreshLayout pullToRefresh = rootView.findViewById(R.id.swipe_refresh_layout_order_history);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// load orders
pullToRefresh.setRefreshing(false);
}
});
lvOrders.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
}
});
return rootView;
}
and similar kind of code goes for FragmentHome
The Problem
I can move between fragments and the view works fine.
Now from Account fragment, I move to AccountEditActivity
I do some update there and come back to MainActivity by pressing hardware back button
FragmentHome is displayed fine but when I click on FragmentAccount, screen goes blank
Now, if I click on Home fragment and click FragmentAccount again, it displays fine.
What is wrong here?
better use viewpager in your activity to show the fragments
it's easy to manage while using viewpagers
have a look at the link
Fragments in viewpager
and in your case just move this code from onCreate to onResume
setFragment(FragmentMainHome.getInstance());
for understanding better have a look at the lifecycle of activity in android
Activity life cycle
I have set recycler view in one fragment which consist of 20 records.When I click on any one of cardview a swipeard is displayed in next Fragment.I am passing some data from cardview to swipecard.I need to set all 20 SwipeCards after moving to SwipeCard Fragment.But only one SwipeCard is displayed.
This is code for setting swipecard
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v=inflater.inflate(R.layout.temp_user_status_info, container, false);
swipeCardsView=(SwipeCardsView)v.findViewById(R.id.swipeCard);
infoAdapter=new CurrentInfoAdapter(info,getActivity());
swipeCardsView.retainLastCard(false);
swipeCardsView.enableSwipe(true);
person_name=getArguments().getString("name");
person_people=getArguments().getString("people");
person_estimate=getArguments().getString("estimate");
CurrentInfo currentInfo=new CurrentInfo();
currentInfo.setName(person_name);
currentInfo.setPeople(person_people);
currentInfo.setEstimate(person_estimate);
Log.i("name",person_name);
Log.i("people",person_people);
Log.i("estimate",person_estimate);
info.add(currentInfo);
swipeCardsView.setAdapter(infoAdapter);
return v;
This is code for RecyclerView Adapter from where I am passing data to SwipeCardView
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final CurrentEntry current=filterList.get(position);
// holder.number.setText(current.getNo());
holder.Name.setText(current.getName());
holder.People.setText(current.getPeople());
holder.Estimate.setText(current.getEstimate());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name=current.getName();
String people=current.getPeople();
String estimate=current.getEstimate();
Bundle args=new Bundle();
args.putString("name",name);
args.putString("people",people);
args.putString("estimate",estimate);
// UserSatusInfo satusInfo=new UserSatusInfo();
// satusInfo.setArguments(args);
TempUserStatusInfo info=new TempUserStatusInfo();
info.setArguments(args);
AppCompatActivity activity=(AppCompatActivity)v.getContext();
// activity.getSupportFragmentManager().beginTransaction().replace(R.id.frame,satusInfo).addToBackStack("info").commit();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.frame,info).addToBackStack("info").commit();
Toast.makeText(v.getContext(),name,Toast.LENGTH_SHORT).show();
Log.i("name",name);
}
});
How to get all Cards at a same time after clicking any one card from Recycclerview
You can pass you complete arraylist
bundle.putSerializable("key", ArrayList<T extends Serializable> list);
and then in fragment recieve
ArrayList<T extends Serializable> transactionList = (ArrayList<T extends Serializable>)getArguments().getSerializable("key");
Hope this helps.
I have been searching this but I haven't found anything that could help me.
I have a main activity with 2 fragments which I use as tabs in my toolbar. Is there any possibility of connecting an ImageButton from a fragment in my MainActivity to an other Activity. I know how to connect Activity to Activity through an imagebuttom, i just don't know how to do it from Fragment-> Activity. Thanks.
I have an image button on my fragment, and I want to open an activity when I press that ImageButton.
public class Movies extends Fragment {
public Movies() {
// Required empty public constructor
}
ImageButton imageButton2;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_movies, container, false);
imageButton2 = (ImageButton) findViewById(R.id.imageButton2);
imageButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intentLoadNewActivity = new Intent(Movies.this, Activity_Civil_War.class);
startActivity(intentLoadNewActivity);
}
});
}
}
I am getting lots of errors. I also tried doing it in the MainActivity but I get the null object exception.
MainActivity Class:
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
TabLayout tabLayout;
ViewPager viewPager;
view_pager_adapter viewPagerAdapter;
ImageButton imageButton2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=(Toolbar)findViewById((R.id.toolBar));
tabLayout=(TabLayout)findViewById((R.id.tabLayout));
viewPager=(ViewPager)findViewById((R.id.ViewPager));
viewPagerAdapter = new view_pager_adapter(getSupportFragmentManager());
viewPagerAdapter.addFragments(new Showcase(),"Showcase");
viewPagerAdapter.addFragments(new Movies(),"Movie List");
viewPagerAdapter.addFragments(new Menu(),"Menu");
viewPagerAdapter.addFragments(new Login(),"Login");
viewPager.setAdapter(viewPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
}
Few things first :
return inflater.inflate(R.layout.fragment_movies, container, false);
If your return a value here, the rest of the code below it will not be called. What you need to do is keep a reference to it and return it at the end of your method.
Then
Intent intentLoadNewActivity = new Intent(Movies.this, Activity_Civil_War.class);
I assume that Movies is a Fragment and Activity_Civil_War is an Activity (correct me if I'm wrong).
There is no constructor in the Intent class that takes a Fragment as a parameter. What you are trying to do by calling 'this' is to get a Context. In a Fragment you can do so by calling getActivity()
If we sum things up we get :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_movies, container, false);
imageButton2 = (ImageButton) findViewById(R.id.imageButton2);
imageButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intentLoadNewActivity = new Intent(getActivity(), Activity_Civil_War.class);
startActivity(intentLoadNewActivity);
}
});
return view;
}
I'm trying to create a viewpager where the user can tap a photo and the photo will take a 'highlighted' state.
I achieve the 'highlighted' state by setting a FrameLayout overlay above the image. The problem is when i swipe trough the pages the state is not only lost but it appears on non selected images.
This is my viewpager adapter:
public class ImageSliderAdapter extends FragmentPagerAdapter {
//Image ids from constants
private int[] Images = Constants.Images;
private int mCount = Images.length;
public ImageSliderAdapter$Adapter(FragmentManager fm) {
super(fm);
}
// The displayed fragment for each position
#Override
public FragmentImageSlider getItem(int position) {
return FragmentImageSlider.newInstance(Images[position];
}
#Override
public int getCount() {
return mCount;
}
}
And this is the fragment that the viewpager returns:
public class FragmentImageSlider extends Fragment {
//Image resource id to show
int imageResourceId;
//Image view of the pic displayed
ImageView image;
// View to indicate highlighted images
View highliteView;
public static FragmentImageSlider newInstance(int imageResourceId){
FragmentImageSlider f = new FragmentImageSlider();
Bundle b = new Bundle();
b.putInt("image", imageResourceId);
f.setArguments(b);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (getArguments() !=null) {
//get image resource id from extras
imageResourceId = getArguments().getInt("image");
}
View root = inflater.inflate(R.layout.displayLayout, null);
image = (ImageView) root.findViewById(R.id.imageView);
highliteView = root.findViewById(R.id.highliteView);
image.setImageResource(imageResourceId);
//When the image is clicked, toggle the highlighted state
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//toggle state
//this view has a selector and changes when selected
highliteView.setSelected(!highliteView.isSelected());
}
});
return root;
}
}
So my question is, how can i keep the highlighted state?
You can change the visibility of your highlight view instead of selected state.
By default set the visibility of highlight view as GONE and when the image is selected change it to visible.
highliteView.setVisibility(View.GONE);
// when the image is clicked show the highlighted view
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
highliteView.setVisibility(View.VISIBLE);
}
});
According to the [FragmentPagerAdapter document](view hierarchy may be destroyed when not visible),
The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible
The view maybe reloaded from default layout when it go out of the view, that's why the highlight state is lost.
You should keep the highlight state in your Fragment:
public MyFragment extends Fragment{
//variable to keep the state
private boolean highlight;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//rest of your other code
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
highliteView.setSelected(!highliteView.isSelected());
//set the highlight state when clicked
highlight = !highliteView.isSelected();
}
});
return root;
}
//set the view state to the image view
public void onViewCreated(View view, Bundle savedInstanceState){
highliteView.setSelected(highlight);
}
}