Fragment Shared Element showing abnormal behaviour in transition - android

Here is my code:
DetailsFragment fragment = new DetailsFragment();
Transition changeTransform = TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform);
Transition explodeTransform = TransitionInflater.from(getActivity()).
inflateTransition(android.R.transition.explode);
setSharedElementReturnTransition(changeTransform);
setExitTransition(explodeTransform);
// Setup enter transition on second fragment
fragment.setSharedElementEnterTransition(changeTransform);
fragment.setEnterTransition(explodeTransform);
FragmentManager manager = ((Activity)mContext).getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.layoutView, fragment).addToBackStack(fragment.getClass().getSimpleName())
.addSharedElement(view.findViewById(R.id.itemView), "view");
fragment.commit();
In DetailsFragment giving the same transition name("view" as Assign a Common Transition Name) in Layout for ImageView but I not able to see any transition on Android Lollipop.
I have already declared the manifests file style for (Enable Window Content Transitions) -
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowContentTransitions">true</item>
</style>
I have searched a lot but didn't get answer.

First need to Create
transition directory under project res directory.
Create change_image_trans.xml under transition directory.
<?xml version="1.0" encoding="utf-8"?>
<transitionSet>
<changeTransform/>
<changeBounds/>
</transitionSet>
Activity like this -
public class DemoActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
ListFragment listFragment = new ListFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, listFragment)
.commit();
}
}
My Activity fragment like this -
activity_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
here is my fragment to open -
ListFragment.java
public class ListFragment extends Fragment implements AbsListView.OnItemClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
ListView listView = (ListView) view.findViewById(R.id.listView);
String [] strings = {"First Element", "Second Element", "Third Element"};
MyListAdapter myListAdapter = new MyListAdapter(getActivity(), R.layout.list_item, strings);
listView.setAdapter(myListAdapter);
listView.setOnItemClickListener(this);
return view;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String imageTransitionName = "";
String textTransitionName = "";
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
TextView textView = (TextView) view.findViewById(R.id.textView);
ImageView staticImage = (ImageView) getView().findViewById(R.id.imageView);
LastFragment lastFragment = new LastFragment();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setSharedElementReturnTransition(TransitionInflater.from(
getActivity()).inflateTransition(R.transition.change_image_trans));
setExitTransition(TransitionInflater.from(
getActivity()).inflateTransition(android.R.transition.fade));
lastFragment.setSharedElementEnterTransition(TransitionInflater.from(
getActivity()).inflateTransition(R.transition.change_image_trans));
lastFragment.setEnterTransition(TransitionInflater.from(
getActivity()).inflateTransition(android.R.transition.fade));
imageTransitionName = imageView.getTransitionName();
textTransitionName = textView.getTransitionName();
}
Bundle bundle = new Bundle();
bundle.putString("TRANS_NAME", imageTransitionName);
bundle.putString("ACTION", textView.getText().toString());
bundle.putString("TRANS_TEXT", textTransitionName);
bundle.putParcelable("IMAGE", ((BitmapDrawable) imageView.getDrawable()).getBitmap());
lastFragment.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, lastFragment)
.addToBackStack("Payment")
.addSharedElement(imageView, imageTransitionName)
.addSharedElement(textView, textTransitionName)
.addSharedElement(staticImage, getString(R.string.fragment_image_trans))
.commit();
}
}
//MyListAdapter for creating list item
class MyListAdapter extends ArrayAdapter<String> {
public MyListAdapter(Context context, int resource, String[] objects) {
super(context, resource, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = LayoutInflater.from(getContext()).inflate(R.layout.list_item, null);
}
String listItem = getItem(position);
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText(listItem);
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.logo);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
textView.setTransitionName("trans_text" + position);
imageView.setTransitionName("trans_image" + position);
}
return view;
}
}
fragment_list.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:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="80dp"
android:src="#drawable/logo"
android:transitionName="#string/fragment_image_trans"/>
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/imageView">
</ListView>
</RelativeLayout>
LastFragment.java
public class LastFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle bundle = getArguments();
String actionTitle = "DUMMY ACTION";
Bitmap imageBitmap = null;
String transText = "";
String transitionName = "";
if (bundle != null) {
transitionName = bundle.getString("TRANS_NAME");
actionTitle = bundle.getString("ACTION");
imageBitmap = bundle.getParcelable("IMAGE");
transText = bundle.getString("TRANS_TEXT");
}
getActivity().setTitle(actionTitle);
View view = inflater.inflate(R.layout.fragment_last, container, false);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
view.findViewById(R.id.listImage).setTransitionName(transitionName);
view.findViewById(R.id.textView).setTransitionName(transText);
}
((ImageView) view.findViewById(R.id.listImage)).setImageBitmap(imageBitmap);
((TextView) view.findViewById(R.id.textView)).setText(actionTitle);
return view;
}
}
R.layout.fragment_last
<?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:padding="24dp"
android:orientation="vertical">
<ImageView
android:id="#+id/listImage"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:src="#drawable/logo"/>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="Sample"
android:textSize="24sp"/>
<ImageView
android:id="#+id/otherImage"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginTop="24dp"
android:src="#drawable/logo"
android:transitionName="#string/fragment_image_trans"/>
</RelativeLayout>

Related

Shared element back transition not working with recyclerview and cardviews in fragments

I'm trying to create a transition between a recycler view with cardviews fragment to a fragment that only contains 1 card. The problem is that the back transition is not working, while the enter transition is. If I remove setReorderingAllowed(true); then the back transition is working, but the enter transition stops working.
This is what I have.
Fragment with recyclerview with cardviews
public class OrdersFragment extends Fragment implements OrderAdapter.OnOrderListener {
private OrderAdapter mAdapter;
private TextView bonnenTextView;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
postponeEnterTransition();
}
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_bonnen, container, false);
bonnenTextView = view.findViewById(R.id.bonnen_text_view);
RecyclerView orderRecyclerView = view.findViewById(R.id.order_recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
orderRecyclerView.setLayoutManager(layoutManager);
if (mAdapter == null) {
mAdapter = new OrderAdapter(this);
fetchOrders();
}
orderRecyclerView.setAdapter(mAdapter);
return view;
}
private void fetchOrders() {
new OrderFetcher().fetch(new Callback() {
#Override
public void onComplete(Result result) {
if (result instanceof Result.Success) {
mAdapter.setOrders((Order[]) ((Result.Success<?>)result).data);
mAdapter.notifyDataSetChanged();
} else {
Toast.makeText(getContext(), "Could not load orders", Toast.LENGTH_SHORT).show();
}
startPostponedEnterTransition();
}
});
}
#Override
public void onOrderClick(int position, View view, Order order) {
Log.i("OrderClick", "Transition name " + view.getTransitionName());
View carrierTextView = view.findViewById(R.id.carrier_text_view);
View numberTextView = view.findViewById(R.id.id_text_view);
View pickerTextView = view.findViewById(R.id.picker_text_view);
View locationTextView = view.findViewById(R.id.location_text_view);
FragmentTransaction transaction = getParentFragmentManager().beginTransaction();
transaction.addSharedElement(view, view.getTransitionName());
transaction.addSharedElement(carrierTextView, carrierTextView.getTransitionName());
transaction.addSharedElement(numberTextView, numberTextView.getTransitionName());
transaction.addSharedElement(pickerTextView, pickerTextView.getTransitionName());
transaction.addSharedElement(locationTextView, locationTextView.getTransitionName());
transaction.addSharedElement(bonnenTextView, bonnenTextView.getTransitionName());
transaction.replace(R.id.nav_host_fragment, BonFragment.newInstance(view.getTransitionName(), order));
transaction.addToBackStack(null);
transaction.setReorderingAllowed(true);
transaction.commit();
}
}
xml that goes with fragment above
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.orders.OrdersFragment">
<TextView
android:id="#+id/bonnen_text_view"
android:transitionName="bonnen_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="#string/orders"
android:textColor="#color/secondary"
android:textSize="40sp"
android:textStyle="bold"
android:typeface="normal" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/order_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"/>
</LinearLayout>
Fragment with single cardview
public static BonFragment newInstance(String cardTransitionName, Order order) {
BonFragment bonFragment = new BonFragment();
Bundle args = new Bundle();
args.putParcelable("orderParcel", order);
args.putString("cardTransitionName", cardTransitionName);
bonFragment.setArguments(args);
return bonFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View root = inflater.inflate(R.layout.fragment_bon, container, false);
CardView orderCard = root.findViewById(R.id.order_card);
TextView carrierTextView = root.findViewById(R.id.carrier_text_view);
TextView numberTextView = root.findViewById(R.id.id_text_view);
TextView pickerTextView = root.findViewById(R.id.picker_text_view);
TextView locationTextView = root.findViewById(R.id.location_text_view);
if (getArguments() != null && getArguments().getParcelable("orderParcel") != null) {
Order order = getArguments().getParcelable("orderParcel");
orderCard.setTransitionName(getArguments().getString("cardTransitionName"));
if (order != null) {
carrierTextView.setTransitionName("carrier" + order.getIndex());
carrierTextView.setText(order.getCarrier());
numberTextView.setTransitionName("number" + order.getIndex());
numberTextView.setText(String.valueOf(order.getNumber()));
pickerTextView.setTransitionName("picker" + order.getIndex());
pickerTextView.setText(order.getPicker());
locationTextView.setTransitionName("location" + order.getIndex());
locationTextView.setText(order.getPosition());
carrierTextView.setText("Lorem Ipsum");
numberTextView.setText("Dolor sit amet");
pickerTextView.setText("consectetur adipiscing elit");
locationTextView.setText("Mauris semper");
}
}
orderCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getParentFragmentManager().popBackStack();
}
});
Transition transition = TransitionInflater.from(getContext()).inflateTransition(R.transition.card_transition);
setSharedElementEnterTransition(transition);
setSharedElementReturnTransition(transition);
return root;
}
xml that goes with fragment above
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.orders.OrdersFragment">
<TextView
android:transitionName="bonnen_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="#string/orders"
android:textColor="#color/secondary"
android:textSize="40sp"
android:textStyle="bold"
android:typeface="normal" />
<androidx.cardview.widget.CardView
android:id="#+id/order_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardBackgroundColor="#color/primaryLight"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
android:layout_margin="25dp">
<LinearLayout
android:transitionName="order_card_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="10dp">
<TextView
android:id="#+id/carrier_text_view"
android:transitionName="carrier_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/secondary"
android:textSize="20sp"
android:textStyle="bold"/>
<TextView
android:id="#+id/id_text_view"
android:transitionName="id_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/secondary" />
<TextView
android:id="#+id/picker_text_view"
android:transitionName="picker_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/secondary" />
<TextView
android:id="#+id/location_text_view"
android:transitionName="location_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/secondary" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
This is what it looks like with setReorderingAllowed(true);
This is what it looks like without setReorderingAllowed(true);
EDIT
After applying the answer given by ianhanniballake I got it working.
Here is what I did for future reference.
The only changes I made is in the OrdersFragment class.
I removed the override of the onCreate() method.
I removed the startPostponedEnterTransition(); from my fetchOrders() method and I added
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
postponeEnterTransition();
final ViewGroup parentView = (ViewGroup) view.getParent();
parentView.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
parentView.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
super.onViewCreated(view, savedInstanceState);
}
That's it
As per the Use shared element transitions with a RecyclerView guide, you're calling startPostponedEnterTransition() too early - after setting your data (and calling notifyDataSetChanged() to inform the adapter), you need to wait until the RecyclerView is actually measured and laid out. This requires that you add an OnPreDrawListener and only call startPostponedEnterTransition() once that fires.
In Kotlin you need to start the transition in doOnPreDraw callback of the recyclerView like below:
recyclerView.doOnPreDraw {
startPostponedEnterTransition()
}

Replace fragmentA with fragmentB issue

I have a image in the main activity and when this image is clicked i want to show the fragmentA that has a list view.
When a item of this listView is clicked i want to replace the fragmentA by the fragmentB that has a textview, and I want to show in this textview the text associated to the clicked list item.
So in main activity I have this:
public class MainActivity extends AppCompatActivity implements Listener{
private ImageView img;
private String text;
FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
img = (ImageView) findViewById(R.id.imageView);
}
public void AddFragmentA(View view) {
FragmentA fragmentA = new FragmentA();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.containerFragmentA, new FragmentA(), "fragA");
transaction.commit();
}
public void AddFragmentB() {
FragmentB fragment = new FragmentB();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.containerFragmentB, new FragmentA(), "fragB");
transaction.commit();
}
#Override
public void addText(String text) {
this.text = text;
Toast.makeText(this, "Text received in Activity:" +text, Toast.LENGTH_SHORT).show();
sendDataToFragmentB();
}
public void sendDataToFragmentB(){
FragmentB fragmentB = (FragmentB) fragmentManager.findFragmentByTag("fragB");
fragmentB.addText(text);
}
}
Note: The toast in addText() appears with the correct text at this point, so the text of the list view is received in Activity with success.
Question: Now how to replace fragmentA with fragmentB and show the textview with the received text in the activity instead of showing the listview of the fragmentA?
Below is all the complete example.
FragmentA class:
public class FragmentA extends Fragment{
private ListView listItems;
private String[] items = {
"item1",
"item2",
"item3",
"item4"
};
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listItems = (ListView) getView().findViewById(R.id.listviewInFragment);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(getActivity().getApplicationContext(),
android.R.layout.simple_list_item_1, android.R.id.text1, items);
listItems.setAdapter(adapter);
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
int positionCode = i;
String clickedValue = (String) adapterView.getItemAtPosition(i);
Listener listener = (Listener) getActivity();
listener.addText(clickedValue);
}
});
}
}
FramentB:
public class FragmentB extends Fragment {
private TextView tv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
tv = (TextView) getView().findViewById(R.id.textView);
return view;
}
public void addText(String text) {
String result = text;
tv.setText(result);
}
}
main 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">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/image"
android:onClick="AddFragmentA"
tools:layout_editor_absoluteX="0dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp" />
<FrameLayout
android:id="#+id/containerFragmentA"
android:layout_width="0dp"
android:layout_height="300dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.0"
tools:layout_editor_absoluteY="1dp">
</FrameLayout>
<FrameLayout
android:id="#+id/containerFragmentB"
android:layout_width="0dp"
android:layout_height="300dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.0"
tools:layout_editor_absoluteY="1dp">
</FrameLayout>
</android.support.constraint.ConstraintLayout>
fragment a xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0ff">
<ListView
android:layout_width="368dp"
android:layout_height="495dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="16dp"
android:id="#+id/listviewInFragment"/>
</android.support.constraint.ConstraintLayout>
fragment b xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
/>
</android.support.constraint.ConstraintLayout>
This is how you will achieve the required task.
make chnages to your class accordingly below.
MainActivity.java
public class MainActivity extends AppCompatActivity implements FragmentA.ClickListener{
private Button button;
public static String EXTRA_STRING = "extraString";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AddFragment(FragmentA.getInstance());
}
});
}
public void AddFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.containerFragmentA, fragment).commit();
}
#Override
public void onClick(String data) {
AddFragment(FragmentB.getInstance(data));
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/containerFragmentA"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteY="1dp"/>
<Button
android:id="#+id/button"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_margin="8dp"
android:layout_alignParentBottom="true"
android:text="Add Fragment B"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
FragmentA.java
public class FragmentA extends Fragment {
private ListView listItems;
private String[] items = {"item1", "item2", "item3", "item4"};
private ClickListener clickListener;
public static FragmentA getInstance() {
return new FragmentA();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
clickListener = (ClickListener)context;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
listItems = (ListView) getView().findViewById(R.id.listviewInFragment);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1, items);
listItems.setAdapter(adapter);
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String clickedValue = items[i];
clickListener.onClick(clickedValue);
}
});
}
public interface ClickListener{
void onClick(String data);
}
}
fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="368dp"
android:layout_height="495dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="16dp"
android:id="#+id/listviewInFragment"/>
</android.support.constraint.ConstraintLayout>
FragmentB.java
public class FragmentB extends Fragment {
private TextView tv;
private String data;
public static FragmentB getInstance(String data){
Bundle bundle = new Bundle();
bundle.putString(MainActivity.EXTRA_STRING,data);
FragmentB fragmentB = new FragmentB();
fragmentB.setArguments(bundle);
return fragmentB;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
tv = view.findViewById(R.id.textView);
data = getArguments().getString(MainActivity.EXTRA_STRING);
addText(data);
return view;
}
public void addText(String text) {
String result = text;
tv.setText(result);
}
}
fragment_b.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_gravity="center"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:gravity="center"
android:textSize="24dp"
android:textAppearance="#style/TextAppearance.AppCompat.Widget.PopupMenu.Header"
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
you are placing fragment A in below function instead of fragment B
public void AddFragmentB() {
FragmentB fragment = new FragmentB();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.containerFragmentB, new FragmentA(), "fragB");
transaction.commit();
}
it should be
public void AddFragmentB() {
FragmentB fragment = new FragmentB();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.containerFragmentB, new FragmentB(), "fragB");
transaction.commit();
}
if you want to replace a fragment with another just use the same container
don't create separate (R.id.containerFragmentB, R.id.containerFragmentA) container.
You need to change your
public void AddFragmentA(View view) {
FragmentA fragmentA = new FragmentA();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.containerFragmentA, new FragmentA(), "fragA");
transaction.commit();
}
public void AddFragmentB() {
FragmentB fragment = new FragmentB();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.containerFragmentB, new FragmentA(), "fragB");
transaction.commit();
}
to
public void AddFragmentA(View view) {
FragmentA fragmentA = new FragmentA();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.container, fragmentA , "fragA");
transaction.commit();
}
public void AddFragmentB() {
FragmentB fragment = new FragmentB();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.container, fragment, "fragB");
transaction.commit();
}
and activity_main.xml should be
<?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">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/image"
android:onClick="AddFragmentList"
tools:layout_editor_absoluteX="0dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp" />
<FrameLayout
android:id="#+id/container"
android:layout_width="0dp"
android:layout_height="300dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.0"
tools:layout_editor_absoluteY="1dp">
</FrameLayout>
</android.support.constraint.ConstraintLayout>
EDIT
listItems.setAdapter(adapter);
listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
int positionCode = i;
String clickedValue = (String) adapterView.getItemAtPosition(i);
Listener listener = (Listener) getActivity();
listener.addText(clickedValue);
}
});
Listener
public interface IScanner {
void addText(String Text);
}
MainActivity
public class MainActivity extends AppCompatActivity implements Listener{
private ImageView img;
private String text;
FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
img = (ImageView) findViewById(R.id.imageView);
}
public void AddFragmentA(View view) {
FragmentA fragmentA = new FragmentA();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.containerFragmentA, new FragmentA(), "fragA");
transaction.commit();
}
#Override
public void addText(String text) {
this.text = text;
Toast.makeText(this, "Text received in Activity:" +text, Toast.LENGTH_SHORT).show();
sendDataToFragmentB(text);
}
public void sendDataToFragmentB(String clickedValue){
Bundle b = new Bundle();
b.putString("clickedValue", clickedValue);
FragmentB fragment = new FragmentB();
fragment.setArguments(b);
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.containerFragmentB, new FragmentA(), "fragB");
transaction.commit();
}
}
FragmentB
public class FragmentB extends Fragment {
private TextView tv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
tv = (TextView) getView().findViewById(R.id.textView);
return view;
}
Bundle bundle = this.getArguments();
if (bundle != null) {
String text = bundle.getString("clickedValue", "");
}
}
This will solve your problem

UI appearance changed after switching from activity to fragment

I had an activity with a Listview containing text and green squares. I finally changed my mind and modified my code to use a fragment instead of an activity. But then my text color changed and I can't see the green squares anymore. I didn't changed anything in my list code or the color of the text so I don't understand what's happening.
Thank you for your help.
MainActivity is only used as a fragment container :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.ll_container);
if (fragment == null) {
fragment = new PollutionLevelsFragment();
fm.beginTransaction()
.add(R.id.ll_container, fragment)
.commit();
}
}
}
MainActivity layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
The fragment class
public class PollutionLevelsFragment extends Fragment implements PollutionLevelsFragmentMVP.View {
private PollutionLevelAdapter plAdapter;
#BindString(R.string.city)
String city;
#BindString(R.string.aqicn_token)
String authToken;
#BindView(R.id.lv_pollution_levels)
ListView lvPollutionLevels;
#Inject
PollutionLevelsFragmentMVP.Presenter presenter;
private ViewModel pollutionData;
private ArrayList<String> testbidon;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_pollution_levels, container, false);
ButterKnife.bind(this,view);
// Construct the data source
ArrayList<PollutionLevel> arrayOfPollutionLevel = new ArrayList<>();
// Create the adapter to convert the array to views
plAdapter = new PollutionLevelAdapter(getActivity().getApplicationContext(), arrayOfPollutionLevel);
lvPollutionLevels.setAdapter(plAdapter);
return view;
}
#Override
public void onStart() {
super.onStart();
presenter.setView(this);
presenter.loadData(city, authToken);
}
#Override
public void onStop() {
super.onStop();
presenter.rxUnsubscribe();
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((App) getActivity().getApplication()).getComponent().inject(this);
}
#Override
public void updateData(ViewModel viewModel) {
this.pollutionData = viewModel;
ArrayList<PollutionLevel> pollutionLevels = viewModel.getAllPolluants();
for(PollutionLevel pl : pollutionLevels) {
plAdapter.add(pl);
}
}
}
The fragment layout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:id="#+id/lv_pollution_levels"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
The ArrayAdapter for the ListView
public class PollutionLevelAdapter extends ArrayAdapter<PollutionLevel> {
#BindView(R.id.tv_name)
TextView tvName;
#BindView(R.id.tv_value)
TextView tvValue;
public PollutionLevelAdapter(Context context, ArrayList<PollutionLevel> pollutionLevels) {
super(context,0,pollutionLevels);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_pollution, parent, false);
}
View view = convertView;
ButterKnife.bind(this,view);
PollutionLevel pollutionLevel = getItem(position);
tvName.setText(pollutionLevel.getName());
tvValue.setText(pollutionLevel.getValue());
return view;
}
}
My list item
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_warning"
android:layout_width="20dp"
android:layout_height="20dp"
app:srcCompat="#drawable/rectangle"/>
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:text="TextView"/>
<TextView
android:id="#+id/tv_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:text="TextView"/>
This is the code of the layout the Activity class that rendered the Listview correctly (so before I switched from an activity to a fragment). I didn't put the code of the Listview adapter here since it didn't change :
Activity
public class PollutionLevelsActivity extends AppCompatActivity implements PollutionLevelsActivityMVP.View {
private PollutionLevelAdapter plAdapter;
#BindString(R.string.city)
String city;
#BindString(R.string.aqicn_token)
String authToken;
#BindView(R.id.lv_pollution_levels)
ListView lvPollutionLevels;
#Inject
PollutionLevelsActivityMVP.Presenter presenter;
private ViewModel pollutionData;
private ArrayList<String> testbidon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((App) getApplication()).getComponent().inject(this);
ButterKnife.bind(this);
// Construct the data source
ArrayList<PollutionLevel> arrayOfPollutionLevel = new ArrayList<>();
// Create the adapter to convert the array to views
plAdapter = new PollutionLevelAdapter(this, arrayOfPollutionLevel);
lvPollutionLevels.setAdapter(plAdapter);
}
#Override
protected void onStart() {
super.onStart();
presenter.setView(this);
presenter.loadData(city, authToken);
}
#Override
protected void onDestroy() {
super.onDestroy();
presenter.rxUnsubscribe();
}
#Override
public void updateData(ViewModel viewModel) {
this.pollutionData = viewModel;
ArrayList<PollutionLevel> pollutionLevels = viewModel.getAllPolluants();
for(PollutionLevel pl : pollutionLevels) {
plAdapter.add(pl);
}
}
}
Layout
<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.livos.citypollution.pollutionlevels.PollutionLevelsActivity">
<ListView
android:id="#+id/lv_pollution_levels"
android:layout_width="368dp"
android:layout_height="495dp"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
To change Text Color add this
android:textColor="Your Color Code"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_warning"
android:layout_width="20dp"
android:layout_height="20dp"
**app:src="#drawable/rectangle"**/>
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:text="TextView"
android:textColor="Your Color Code"/>
<TextView
android:id="#+id/tv_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="center_vertical"
android:text="TextView"
android:textColor="Your Color Code"/>
As i am getting. You give an adapter like:
public class PollutionLevelAdapter extends ArrayAdapter<PollutionLevel> {
#BindView(R.id.tv_name)
TextView tvName;
#BindView(R.id.tv_value)
TextView tvValue;
public PollutionLevelAdapter(Context context, ArrayList<PollutionLevel> pollutionLevels) {
super(context,0,pollutionLevels);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_pollution, parent, false);
}
View view = convertView;
ButterKnife.bind(this,view);
PollutionLevel pollutionLevel = getItem(position);
tvName.setText(pollutionLevel.getName());
tvValue.setText(pollutionLevel.getValue());
return view;
}
}
You are binding your two TextView not Your ImageView as you gave your list_item_pollution, which is having ImageView so bind your ImageView like:
#BindView(R.id.iv_warning)
ImageView iv_warning;
and in getView method set is as :
iv_warning.setBackgroundColor(Color.parseColor("your color code"));

How to add fragment int the right item when tap on the gridview item

Here is my CategoryFragment:
public class CategoryFragment extends Fragment implements CategoriesItemsAdapter.CategoriesDelegate {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_budget,container,false);
mSavedInstanceState= savedInstanceState;
return mView;
}
private void setGridViewAdapter(ArrayList<String> texts, ArrayList<Integer> icons){
mCategories = (GridView) mView.findViewById(R.id.categories);
CategoriesItemsAdapter adapter = new CategoriesItemsAdapter(getActivity(),texts,icons);
adapter.CategoriesDelegate = this;
mCategories.setAdapter(adapter);
}
#Override
public void categoriesDelegate() {
MainActivity activity = (MainActivity) getActivity();
FragmentManager manager = activity.getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
if (mSavedInstanceState == null) {
transaction.replace(R.id.categories_frame, new CategoriesFragment());
}
transaction.addToBackStack(null);
transaction.commit();
}
}
Here is my CategoriesItemsAdapter:
public class CategoriesItemsAdapter extends BaseAdapter implements View.OnClickListener {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_categories, parent, false);
}
ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
TextView text = (TextView) convertView.findViewById(R.id.category_name);
text.setText(mTexts.get(position));
icon.setImageResource(mIcons.get(position));
icon.setOnClickListener(this);
return convertView;
}
#Override
public void onClick(View v) {
if (CategoriesDelegate != null) {
CategoriesDelegate.categoriesDelegate();
}
}
public interface CategoriesDelegate {
void categoriesDelegate();
}
}
I want to open a fragment when I click on the a grid view item. I can open a fragment but the fragment is opening in the wrong place. Fragment always opens in the first item. Which grid view item I clicked on in that grid view item,fragment should be opened. How I can solve this problem?
And here is my items_categories.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<!-- Icon -->
<ImageView
android:id="#+id/icon"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
/>
<FrameLayout
android:id="#+id/categories_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
>
<!-- Category Name -->
<TextView
android:id="#+id/category_name"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_gravity="center"
android:gravity="center"
/>
</FrameLayout>

How to use same fragment in a viewPager?

I develope currently a small sample app with fragments and a viewPager. The viewPager shows 3 pages. In each page i instantiate a fragment of the same type. The fragment contains a textView and a button. On button click I want to replace the current fragment with another one. Now my problem is, no matter which button I press only the fragment of page 1 gets replaced. I dont know what I have to do in my pageAdapter class but I guess it has to do with using the same fragment and layout. I think I have to make sure, that my pageAdapter updates the correct page, but how do I achieve that?
For a better understanding why I want to achieve that, that I receive a json string within 3 node of type menu and I want to use each of them as a page in my viewPager.
Can someone show me a short and easy example for such a behavior? I think its a basic approach, so it cant be so difficult.
--------Edit---------
Here is the code:
public class FragmentPagerSupport extends FragmentActivity {
static final int NUM_ITEMS = 4;
MyAdapter mAdapter;
ViewPager mPager;
#Override
public void onBackPressed() {
FragmentManager fm = getFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
} else {
super.onBackPressed();
}
}
public MyAdapter getmAdapter() {
return mAdapter;
}
public ViewPager getmPager() {
return mPager;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_pager);
mAdapter = new MyAdapter(getFragmentManager(), this);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setOffscreenPageLimit(NUM_ITEMS + 2);
mPager.setAdapter(mAdapter);
Button button = (Button) findViewById(R.id.goto_first);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mPager.setCurrentItem(0);
}
});
button = (Button) findViewById(R.id.goto_last);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mPager.setCurrentItem(NUM_ITEMS - 1);
}
});
}
}
MyAdapter:
public MyAdapter(FragmentManager fm, FragmentPagerSupport fragmentPagerSupport) {
super(fm);
this.fragmentPagerSupport = fragmentPagerSupport;
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
Fragment newInstance = null;
switch (position) {
case 0:
newInstance = frag1.newInstance(position);
break;
case 1:
newInstance = frag1.newInstance(position);
break;
case 2:
newInstance = frag2.newInstance(position);
break;
case 3:
newInstance = frag2.newInstance(position);
break;
}
return newInstance;
}
Frag1 & Frag2 & ListItemFrag:
public static class frag1 extends ListFragment {
int mNum;
static frag1 newInstance(int num) {
frag1 f = new frag1();
Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
v.setId(mNum);
View tv = v.findViewById(R.id.text);
((TextView) tv).setText("Fragment #" + mNum);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String[] cheeses = { "Edamer", "Gauda", "Cheddar", "Mozarella", "Maasdamer" };
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, cheeses));
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
String itemName = (String) l.getItemAtPosition(position);
Fragment listItemFragment = ListItemFragment.newInstance(itemName);
FragmentTransaction trans = getActivity().getFragmentManager().beginTransaction();
trans.replace(R.id.root, listItemFragment, listItemFragment.getClass().getName() + "_" + mNum);
trans.addToBackStack(itemName);
trans.commit();
}
}
public static class frag2 extends ListFragment {
int mNum;
static frag2 newInstance(int num) {
frag2 f = new frag2();
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
v.setId(mNum);
View tv = v.findViewById(R.id.text);
((TextView) tv).setText("Fragment #" + mNum);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String[] cheeses = { "Edamer", "Gauda", "Cheddar", "Mozarella", "Maasdamer" };
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, cheeses));
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Log.i("FragmentList", "Item clicked: " + id);
String itemName = (String) l.getItemAtPosition(position);
Fragment listItemFragment = ListItemFragment.newInstance(itemName);
FragmentTransaction trans = getActivity().getFragmentManager().beginTransaction();
trans.replace(R.id.root, listItemFragment, listItemFragment.getClass().getName() + "_" + mNum);
trans.addToBackStack(itemName);
trans.commit();
}
}
public static class ListItemFragment extends Fragment {
String itemName;
static ListItemFragment newInstance(String itemName) {
ListItemFragment i = new ListItemFragment();
Bundle args = new Bundle();
args.putString("text", itemName);
i.setArguments(args);
return i;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
itemName = getArguments() != null ? getArguments().getString("text") : "NULL";
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_item, container, false);
View tv = v.findViewById(R.id.textView1);
((TextView) tv).setText("Cheese: " + itemName + " selected!");
return v;
}
}
Pager Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
<LinearLayout android:orientation="horizontal"
android:gravity="center" android:measureWithLargestChild="true"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="0">
<Button
android:id="#+id/goto_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="first" />
<Button android:id="#+id/goto_last"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="last">
</Button>
</LinearLayout>
Frag1 Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99EE11"
android:id="#+id/test">
<TextView android:id="#+id/text"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/hello_world"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:id="#+id/root" >
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"/>
</FrameLayout>
Frag2 Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99EE11"
android:id="#+id/test2">
<TextView android:id="#+id/text"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/hello_world"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:id="#+id/root2" >
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"/>
</FrameLayout>
ListItemFrag Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="230dp"
android:background="#AA33EE"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
Hi I was facing same kind of issue. I fixed the issue by using
getChildFragmentManager().beginTransaction()
instead of
getActivity().getSupportFragmentManager().beginTransaction()
As in this case we are trying to make transaction from within a fragment (one out of the list of fragments which are attached to the ViewPager, thus the Activity holding the ViewPager) so we have to use getChildFragmentManager() here for desired results.
NOTE: I am using android support v4 library and thus corresponding FragmentManager.

Categories

Resources