I am trying to get the data from previous Activity to a Fragment. I am able to get the data without Fragment but, when I put the code inside Fragment, it doesn't work. My Fragment is inside description class. Here is my code:
This is how I am sending data from previous Activity:
TextView textView = (TextView) view.findViewById(R.id.txt_name);
String text = textView.getText().toString();
if(text.equals("ADA")) {
intent = new Intent(view.getContext(), description.class);
intent.putExtra("ADA", text);
startActivity(intent);
}
This is how I am getting it inside Fragment:
public static class DummyFragment extends Fragment {
int color;
TextView mTextview;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
mTextview = (TextView) view.findViewById(R.id.textView1);
mTextview.setText(getActivity().getIntent().getStringExtra("ADA"));
return view;
}
}
This is my xml code:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dummyfrag_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/bg_light">
<android.support.v7.widget.RecyclerView
android:id="#+id/dummyfrag_scrollableview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_horizontal_margin" />
</FrameLayout>
And:
<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">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="42dp"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
TextView textView = (TextView) view.findViewById(R.id.txt_name);
String text = textView.getText().toString();
if(text.equals("ADA")) {
DummyFragment fragment = new DummyFragment();
Bundle bundle = new Bundle();
bundle.putString("ADA",text);
fragment.setArguments(bundle);
getSupportFragmentManager()
.beginTransaction()
.replace(fragment,R.id.layout)
.addTobackStack(null)
.commit();
}
then in your fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
String text = getArguments().getString("ADA");
}
EDIT
Explaination
1) fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)
Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.
2) fragmentTransaction.add(int containerViewId, Fragment fragment, String tag)
Add a fragment to the activity state. This fragment may optionally also have its view (if Fragment.onCreateView returns non-null) into a container view of the activity.
Use SharedPreferences to store the text. Do this in the Activity before loading fragment
SharedPreferences sharedPreferences = getSharedPreferences("TextHolder", 0);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("ADA", textView.getText().toString()).apply();
Inside the Fragment get the text from SharedPreferences like this
String textHolder = getActivity().getSharedPreferences("TextHolder", 0).getString("ADA", "");
Now set the textHolder String to the TextView of your choice inside the Fragment
Related
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;
}
});
}
Theoretically, lets say i have two classes with corresponding XML files - Activity and Frag
Activity.java
public class Activity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment fragment = new Frag();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragmentArea, fragment);
ft.commit();
}
}
Frag.java
public class Frag extends Fragment {
private TextView txtView;
public Frag() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_, container, false);
txtView = view.findViewById(R.id.textView);
return view;
}
public void setTextView(String str) {
txtView.setText(str);
}
}
activity xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.eksamen.chris.eksempelfragment.Activity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/fragmentArea">
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Fragment xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.eksamen.chris.eksempelfragment.Frag">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment"
android:id="#+id/textView"/>
</FrameLayout>
As you can see, i have the method setTextView() in my Frag class. Obviously enough, what i would like to do is to call that method from my Activity class.
I have tried grasping this for some hours now, and i really cannot figure out a way to do this. Every example/tutorial out there makes my app crash.
Could someone explain to me how this works, taken the example we have in hand into consideration? Or maybe there is a better way to provide the fragment with data from my activity?
I'd be grateful!
Edit: awful indentation, had some issues, trying to fix.
In order to pass data from Activity to Fragment , you have to use :
Bundle
which is a KEY VALUE data structure for passing values between fragments and activity so at your onCreate() in Activity class will be
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String str = "your_string_here";
// 1 -
Bundle bundle = new Bundle();
// 2 -
bundle.putString("KEY", str);
Fragment fragment = new Frag();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// 3 -
fragment.setArguments(bundle);
ft.replace(R.id.fragmentArea, fragment);
ft.commit(); }
and at your fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_, container, false);
txtView = view.findViewById(R.id.textView);
// 4 - NOTE : Should hould the same key at the Activity class :
String str = getArguments().getString("KEY");
setTextView(str);
return view;
}
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");
i have an Activity named MainActivity and a fragment named Fragment!
Fragment is in MainActivity
i want to pass data from MainActivity to Fragment so i used this..
MainActivity onCreate Code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
pager = (ViewPager) findViewById(R.id.pager);
pager.setOffscreenPageLimit(0);
pager.setAdapter(adapter);
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(false);
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
tabs.setViewPager(pager);
/*im using appcompat_v7 and above code for material design sliding Tabs*/
/*code for pass data to Fragment*/
Fragment Fragment =new Fragment();
Bundle bundle=new Bundle();
bundle.putString("name", "myname");
Fragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.pager, Fragment).commit();
}
and then i retrieve data and want to change UI like this!
Fragment onCreateView Code:
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1,container,false);
Bundle bundle = getArguments();
if (bundle != null){
name= bundle.getString("name");
Toast.makeText(getActivity(), name+"", 1000).show();
/*change UI*/
TextView tv= (TextView) v.findViewById(R.id.tv);
tv.setText(name);
}
return v;
}
but the problem is here! i dont know why tv show nothing in screen while Toast return name and dont know why next time when i get tv text, it show that name with toast!
what happens here? someone help me plz
Edit:
tab_1 xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e3dbdb"
android:orientation="vertical" >
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#_#"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
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", "");