i get a empty fragments when i try replace - android

I'd like to replace a fragment in viewpager and I wrote my code , i do
on't get some errors , but i get an empty fragemnt , however the fragment has layout. I'd like to get it from a listview onitemclick.
here is my fragment replace. I really don't know where i do make mistake.
Thank you for help.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Fragment dogProfile = new ProfileDogFragment();
Bundle bundle = new Bundle();
bundle.putString("DOG_NAME", dogList.get(position).getName());
bundle.putInt("DOG_PROFILE_PICTURE",dogList.get(position).getImgId());
dogProfile.setArguments(bundle);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.viewpager,dogProfile);
ft.addToBackStack(null);
ft.commit();
}

Here is the pager 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".activities.MainActivity"
android:orientation="vertical">
<include layout="#layout/toolbar" android:id="#+id/main_toolbar"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ffffff"/>
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextAppearance="#style/MineCustomTabText"
app:tabTextColor="#ffffff"
app:tabSelectedTextColor="#A9A9A9"
android:background="#color/menu_bottom_bar"
/>
here is the listfragment:
public class ListDogFragment extends ListFragment {
ArrayList<Dog> dogList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.list_dog,container,false);
dogList = new ArrayList<Dog>();
dogList.add(new Dog("Bolyhos",123,2,R.drawable.asd,"male","black and
white","Border Collie",null,"This is my dog",false));
setListAdapter(new DogListAdapter(getActivity(),dogList));
return root;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Nullable
public View getView(int position, View convertView, ViewGroup parent) {
return convertView;
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Fragment dogProfile = new ProfileDogFragment();
Bundle bundle = new Bundle();
bundle.putString("DOG_NAME", dogList.get(position).getName());
bundle.putInt("DOG_PROFILE_PICTURE",dogList.get(position).getImgId());
dogProfile.setArguments(bundle);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.viewpager,dogProfile);
ft.addToBackStack(null);
ft.commit();
}
}
and the last , the dog profile what i want to replace from list.
public class ProfileDogFragment extends Fragment{
TextView dogName;
ImageView dogProfileImageId;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup
container, #Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.profile_dog,container,false);
dogName = (TextView) root.findViewById(R.id.dogProfileName);
dogProfileImageId = (ImageView)
root.findViewById(R.id.dogProfilePicture);
Bundle bundle = this.getArguments();
String name = bundle.getString("DOG_NAME");
int picture = bundle.getInt("DOG_PROFILE_PICTURE");
dogName.setText(name);
dogProfileImageId.setImageResource(picture);
return root;
}
}

Related

How to used a shared transition from RecyclerView to a Fragment

I've seen this questioned asked a number of times on here without an answer. I'm hoping if I ask it again maybe someone will be kind enough to help me with it.
I'm trying to implement a shared transition from an Item in a Recyclerview to a fragment.
I currently have my fragment transaction in the onBindView method of the adapter.
public void onClick(View v) {
...
activity.getSupportFragmentMnager().beginTransaction()
.addSharedElement(v, "SharedString")
.replace(R.id.container, fragment2)
.addToBackStack(null)
.commit();
}
In the android docs, addSharedElement(view and string) confuse me. How do I give the view a unique ID and should I even be using v here?
Can the string be what ever I want?
here is my implementation. There is FragmentList with RecyclerView with images on each item. And there is FragmentDetail with only on big image. Image from FragmentList list item fly to FragmentDetail. TransitionName of animated view on FragmentList and FragmentDetail must be same. So I give unique transition name for each list item ImageView:
imageView.setTransitionName("anyString" + position)
Then I pass that string to FragmentDetail via setArguments and set big image transitionName to that string. Also we should provide Transition which describes how view from one view hierarchy animates to another viewhierarchy. After that we should pass that transition to fragment. I do it before FragmentTransaction:
detailFragment.setSharedElementEnterTransition(getTransition());
detailFragment.setSharedElementReturnTransition(getTransition());
Or you can override getSharedElementEnterTransition and getSharedElementReturnTransition of Fragment and declare transition there. Here is full code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, new FragmentList())
.commit();
}
}
public void showDetail(View view) {
String transitionName = view.getTransitionName();
FragmentDetail fragment = new FragmentDetail();
fragment.setArguments(FragmentDetail.getBundle(transitionName));
fragment.setSharedElementEnterTransition(getTransition());
fragment.setSharedElementReturnTransition(getTransition());
getSupportFragmentManager()
.beginTransaction()
.addSharedElement(view, transitionName)
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
}
private Transition getTransition() {
TransitionSet set = new TransitionSet();
set.setOrdering(TransitionSet.ORDERING_TOGETHER);
set.addTransition(new ChangeBounds());
set.addTransition(new ChangeImageTransform());
set.addTransition(new ChangeTransform());
return set;
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
FragmentList:
public class FragmentList extends Fragment {
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_list, container, false);
RecyclerView rv = view.findViewById(R.id.recyclerview);
rv.setAdapter(new ListAdapter());
return view;
}
private class ListAdapter extends RecyclerView.Adapter {
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Holder hold = (Holder) holder;
hold.itemView.setOnClickListener(v -> {
((MainActivity) getActivity()).showDetail(hold.imageView);
});
//unique string for each list item
hold.imageView.setTransitionName("anyString" + position);
}
#Override
public int getItemCount() {
return 10;
}
private class Holder extends ViewHolder {
ImageView imageView;
public Holder(View view) {
super(view);
imageView = view.findViewById(R.id.image);
}
}
}
}
fragment_list.xml
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
FragmentDetail:
public class FragmentDetail extends Fragment {
private static final String NAME_KEY = "key";
public static Bundle getBundle(String transitionName) {
Bundle args = new Bundle();
args.putString(NAME_KEY, transitionName);
return args;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.fragment_detail, container, false);
String transitionName = getArguments().getString(NAME_KEY);
ImageView imageView = view.findViewById(R.id.image);
imageView.setTransitionName(transitionName);
return view;
}
}
fragment_detail.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="#+id/image"
android:layout_width="300dp"
android:layout_height="300dp"
android:src="#drawable/cat"/>
</LinearLayout>
item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:id="#+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/cat"/>
</LinearLayout>
Here is result:
TransitionName may be any string you want.
There is ViewCompat.setTransitionName if you need support pre Lollipop devices.
Adding to the ashakirov's answer:
Problem
Return Transition was not working!
Reason:
On popbackstack from Fragment B to Fragment A, Fragment A's onCreateView is called and if your data is still loading then the return transition won't work with only ashakirov's code.
Solution
Postpone the transition in your fragments
Add this line where the loading starts in your fragment A:
postponeEnterTransition();
After your data is loaded or you've set your adapter, write this:
startPostponedEnterTransition();
This ensures that your transition only happens after your data is loaded.
Also, make sure you start the transition even in 'data failed to load scenarios'.
If you want to postpone the transition in your fragment B when going from A to B then add this to your fragment B:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//hold the transition
postponeEnterTransition();
//when the views are available then start the transition
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}

Fragment is not showing up in activity

Trying to add Fragment to my Activity, but it isn't showing up.
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WeatherFragment mainFragment = new WeatherFragment();
getFragmentManager()
.beginTransaction()
.add(R.id.main_weather_container, mainFragment)
.commit();
}
}
And there is my fragment:
public class WeatherFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
boolean isAttachedToParent = false;
View inflatedView = inflater.inflate(R.layout.main_weather_fragment, container, isAttachedToParent);
return inflatedView;
}
}
R.id.main_weather_container - FrameLayout in my MainActivity.
R.layout.main_weather_fragment - Fragment's layout
What am i doing wrong?
I've tried to use FragmentActivity + v4 support fragment and fragmentSupportManager, but it didn't make any difference.
MainActivity xml:
<?xml version="1.0" encoding="utf-8"?>
<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">
<FrameLayout
android:id="#+id/main_weather_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="#dimen/padding_16_dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/words_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3" />
</LinearLayout>
UPDATED: The problem wasn't in fragment transaction or whatever, i've used tools: namespace that's why fragment wasn't displayed. Sorry about that :(
try this way .in your activity call fragment
Fragment fragment = Video_fragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.framecontainer, fragment).commit();
in fragment class.
public class Video_fragment extends Fragment{
View view;
public static Fragment newInstance() {
Video_fragment fragment = new Video_fragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view= inflater.inflate(R.layout.video_frag, container, false);
return view;
}
}
Create a instance of Fragment in WeatherFragment:
public static WeatherFragment newInstance() {
Bundle args = new Bundle();
WeatherFragment weatherFragment = new WeatherFragment();
weatherFragment.setArguments(args);
return weatherFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, container, false);
}
Inside your Activity in MainActivity :
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WeatherFragment weatherFragment = WeatherFragment.newInstance();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.flContainerId, weatherFragment)
.commit();
}
Your layout file will be:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/flContainerId"/>
public class WeatherFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View inflatedView = inflater.inflate(R.layout.main_weather_fragment, null, false);
return inflatedView;
}
}
As I can see, you are using AppCompatActivity but using getFragmentManager.
With AppCompatActivity you will need to use getSupportFragmentManager() rather than getFragmentManager()
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WeatherFragment mainFragment = new WeatherFragment();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.main_weather_container, mainFragment)
.commit();
}
}
Your WeatherFragment should be extend android.support.v4.app.Fragment;
<?xml version="1.0" encoding="utf-8"?>
<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:weightSum="4"
android:orientation="vertical">
<FrameLayout
android:id="#+id/main_weather_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="#dimen/padding_16_dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/words_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3" />
</LinearLayout>
Added WeightSum in the parent Layout.

fragment to fragment android call

I want open fragment when I click listitem (fragment) but failed, no error logcat.
fragment_item_two.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="layout.ItemTwoFragment"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- TODO: Update blank fragment layout -->
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</FrameLayout>
fragment1 (listview): (ItemTwoFragment.java)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_item_two, container, false);
BottomNavigationView bottomNavigationView = (BottomNavigationView)
view.findViewById(R.id.navigation);
contactList = new ArrayList<>();
lv = (ListView) view.findViewById(R.id.list);
new GetContacts().execute();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> pa, View v, int p, long id) {
int itm = (int) pa.getItemAtPosition(p);
fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragmentContainer, new NewsFragment());
transaction.commit();
}
});
return view;
}
NewsFragment:
public class NewsFragment extends Fragment {
}
fragment_news:
<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="layout.NewsFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="news fragment" />
</FrameLayout>
how to fix this problem? or can you give me the reference for this case? thanks
you forget to inflate your fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_news, container, false);
// Your code ....
return rootView;
}

activity send data to fragment but what fragment received is null

There is an activity containing a Button and a LinerLayout which is the container of Fragment. The layout of Fragment only contains a TextView. I want to send a string to fragment from activity, but what fragment received is null. Why?
xml of Activity:
<Button
android:id="#+id/load"
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="load" />
<!--the container of fragment-->
<LinearLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" />
xml of Fragment:
<TextView
android:id="#+id/fragment_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Java code of Activity:
public class DynamicFragmentActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_fragment);
findViewById(R.id.load).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//create fragment and set data
MyFragment myFragment = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString("text", "demo");
myFragment.setArguments(bundle);
//commit
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container, myFragment);
fragmentTransaction.commit();
}
});
}
}
Java code of Fragment:
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.myfragment, container, false);
TextView textView = (TextView) view.findViewById(R.id.fragment_text);
//receive data
String text = getArguments().getBundle("text")+"";
textView.setText(text);
return view;
}
}
Try this , Hope it helps ...........
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.myfragment, container, false);
TextView textView = (TextView) view.findViewById(R.id.fragment_text);
//change getBundle() to getString()
String text = getArguments().getString("text")+"";
textView.setText(text);
return view;
}
}
What you are doing now is get a Bundle called text and what you really want is get a string in the bundle:
Bundle arg = getArguments();
String txt = arg.getString("text");

Passing data from ListView to Fragment

I have a ListView in my fist screen that shows some information. When I click on each item, I have another listView with new information and textview in the same page, I want to show the pervious list view row in text view,
would you please let me know how can I implement this,
Thanks in advance!
here is my xml file
<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="######">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:visibility="gone"
android:text="test" />
<TextView
android:id="#+id/list_textview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:text="#string/no_message"
android:textColor="#000000"
android:textAppearance="#android:style/TextAppearance.DeviceDefault.Medium"
android:gravity="center"></TextView>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView" />
</LinearLayout>
Here is my java file that shows the listview and
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
listView = (ListView)view.findViewById(R.id.listView);
listView.setOnItemClickListener(this);
getActivity().getActionBar().setTitle(R.string.title_forms);
TextView details = (TextView)view.findViewById(R.id.detail_header);
details.setVisibility(View.VISIBLE);
return view;
}
Here is one of my fragment that has onItemClick Listener
public class ListFragment extends Fragment implements AdapterView.OnItemClickListener {
public static final String TAG = "ListFragment";
private ListView listView;
private ArrayList<String> testIds;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
tripIds = new ArrayList<String>();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
listView = (ListView) view.findViewById(R.id.listView);
listView.setOnItemClickListener(this);
registerForContextMenu(listView);
return view;
}
Here is my onItemClick :
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
chooseTest(testIds.get(position));
String selectedTestId = testIds.get(position);
Helpers.saveToSharedPreferences(getActivity(),
Constants_Prefs.SELECTED_TOP_LEVEL_RECORD,
Constants_Keys.SELECTED_TEST_ID,
selectedTestId);
I don't know how can I get that information
FormTypeListFragment passDataTo = new FormTypeListFragment();
Bundle bundle = new Bundle();
bundle.putString("DATA", selectedTestId);
passDataTo.setArguments(bundle);
}
Before launching your fragment to display selected item use setArguments() method to add key value pair of string in your case, Then in your fragment on createView use fragments method getArguments() to retain your passed string
Pass the value in bundle as :
Set :
YourFragment fragmnt = new YourFragment ();
Bundle bundle = new Bundle();
bundle.putString("item","name");
fragmnt.setArgument(bundle);
Get :
Then in your Fragment, retrieve the data (e.g. in onCreate()) with:
Bundle bundle = this.getArguments();
String myValue = bundle.getInt("item", "");

Categories

Resources