Look at the sample. I have two scenes, which are start & end scenes.
Layout of start scene:
<?xml version="1.0" encoding="utf-8"?>
<merge
android:id="#+id/vgRoot"
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:parentTag="RelativeLayout"
tools:ignore="HardcodedText"
>
<Button
android:id="#+id/btn1"
style="#style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/cardView"
android:text="Button"
android:layout_centerHorizontal="true"
/>
<Button
android:id="#+id/btnGo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/btn1"
android:text="#string/go"
android:layout_centerHorizontal="true"
/>
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_margin="16dp"
android:translationZ="3dp"
>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#3829AB"
android:padding="32dp"
>
<TextView
android:id="#+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Title"
android:textAppearance="?android:textAppearanceMedium"
android:textColor="#android:color/white"
/>
</FrameLayout>
</android.support.v7.widget.CardView>
</merge>
There i have btn1 for which sliding transition is applied, cardView and container, which change its bounds and tvText as a body of CardView.
And the ending scene:
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:ignore="HardcodedText"
tools:parentTag="RelativeLayout"
>
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:cardCornerRadius="0dp"
>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:background="#3829AB"
android:orientation="vertical"
>
<TextView
android:id="#+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Title"
android:textAppearance="?android:textAppearanceMedium"
android:textColor="#android:color/white"
/>
</FrameLayout>
</android.support.v7.widget.CardView>
</merge>
Fragment code with transition:
public class FragmentStartTransition extends Fragment {
#BindView(R.id.btnGo) View btnGo;
#BindView(R.id.vgRoot) ViewGroup vgRoot;
private Unbinder unbinder;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ViewGroup view = (ViewGroup) inflater.inflate(R.layout.fragment_start_transition, container, false);
unbinder = bind(this, view);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
btnGo.setOnClickListener(btnGo.setOnClickListener(v -> moveNext());
}
#Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
private void moveNext() {
Scene scene = Scene.getSceneForLayout(vgRoot, R.layout.scene_end, getContext());
TransitionManager.go(scene, getTransition());
}
private Transition getTransition() {
Slide slide = new Slide(Gravity.TOP);
slide.addTarget(R.id.btn1);
ChangeBounds changeBounds = new ChangeBounds();
changeBounds.addTarget(R.id.cardView);
changeBounds.addTarget(R.id.container);
changeBounds.addTarget(R.id.tvText);
return new TransitionSet()
.setOrdering(TransitionSet.ORDERING_TOGETHER)
.addTransition(slide)
.addTransition(changeBounds)
.setDuration(1500);
}
}
fragment_start_transition:
<RelativeLayout
android:id="#+id/vgRoot"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="HardcodedText"
>
<include layout="#layout/scene_start"/>
</RelativeLayout>
Result animation:
I want to slide btn1 under the cardView and container. As you can see cardView is placed at the end of root layout to be over button. But in result animation it is slided over the cardView. Can i somehow control such z-axis relations between animated views?
tried cardView.bringToFront() - it doesn't help
there definetely should be simple solution, but i can't find it.
I need your help, guys.
Update:
This is because framework draws slide transition on the scene container view overlay, look at android.transition.Visibility class:
sceneRoot.getOverlay().add(overlayView);
But the question is still opened.
I just solved the same issue. The trick seems to be to not let the Visibility class copy the sliding (disappearing) view to the scene root's overlay, which will obviously be displayed above any other view in the scene.
The sliding view is only copied to the overlay if it is actually removed from the view hierarchy. If I instead leave the view in the scene but set its visibility to GONE, it re-uses the same view instead of copying it to the overlay. Then it will slide beneath its sibling views if it is below them (so your cardView.bringToFront() should work).
Related
I have created a BottomSheetFragment.
Everything is fine except the header of the bottom sheet which is not getting transparent.Is there any way to make the background transparent as like as normal bottomsheetFragment works.
I tried by setting the parent background transparent but it is not working at all.
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/layoutContainer"
android:background="#android:color/transparent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/immediateParent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<com.makeramen.roundedimageview.RoundedImageView xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/imageView"
android:layout_width="#dimen/hundrad_twenty"
android:layout_height="#dimen/hundrad_twenty"
android:layout_centerHorizontal="true"
android:layout_marginTop="#dimen/sixty"
app:riv_border_color="#color/transparent"
app:riv_corner_radius="#dimen/twenty"
app:riv_mutate_background="true"
app:riv_oval="false" />
<ImageView
android:layout_width="#dimen/thirty"
android:layout_height="#dimen/thirty"
android:layout_alignParentRight="true"
android:layout_marginTop="#dimen/hundred_fifty"
android:layout_marginRight="100dp"/>
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
I have tired this.
ConstraintLayout layoutContainer;
RelativeLayout immediateParent;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = null;
view = inflater.inflate(R.layout.bottom_sheet_dialog, container);
ButterKnife.bind(this, view);
//parent layout transparent not working
layoutContainer.setBackground(getResources().getDrawable(R.color.transparent));
immediateParent.setBackground(getResources().getDrawable(R.color.transparent));
//view transparent
view.setBackgroundColor(getResources().getColor(R.color.transparent));
return view;
}
After trying so many ways I found my solution.
Simply added this code in my fragment.
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((View) getView().getParent()).setBackgroundColor(Color.TRANSPARENT);
}
BottomSheetDialog with transparent background
Your view is actually transparent (when you use transparent instead of black obviously), problem is that BottomSheetDialogFragment wraps your view into it's own non-transparent container. Here's how to make that container transparent: https://stackoverflow.com/a/46469709/12976196
I have a ListFragment with a floating action button. When the button is clicked, i want to replace the ListFragment with a CreateListFragment. Instead, the CreateListFragment is placed on top of the ListFragment and the button and textview from the ListFragment are still visible. I am not sure what went wrong. How do I completely replace the ListFragment with the CreateListFragment?
Here is the screenshot before the button is clicked
http://i.stack.imgur.com/k2HxP.png
Here is a screenshot after the button is clicked
http://i.stack.imgur.com/TYN47.png
list_fragment
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listFrame">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/fab"
android:layout_gravity="bottom|end"
app:backgroundTint="#color/colorAccent"
android:src="#drawable/create"/>
<TextView
android:id="#+id/tvEmpty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:hint="No Shopping Lists Yet"
android:layout_gravity="center"
android:textSize="20sp"/>
</FrameLayout>``
createlist_fragment
<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"
android:padding="10dp"
tools:context="com.lavineoluoch.helloworld.swiftpay.app.CreateListFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/etListTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/title"/>
<EditText
android:id="#+id/etAddItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/items"/>
<RelativeLayout
android:id="#+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/btnEditItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btnEdit"
android:background="#color/colorPrimary"
android:textColor="#color/white"
/>
</RelativeLayout>
</LinearLayout>
ListFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.list_fragment, container, false);
fab = (FloatingActionButton)view.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CreateListFragment createListFragment = new CreateListFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.listFrame,createListFragment);
fragmentTransaction.commit();
}
});
return view;
}
In your root view for your Fragments insert this line of code:
android:background="?android:windowBackground"
As you have a see through background your view can still see the reminiscence of the replaced Fragment as the view hasn't yet updated.
The above answer should solve your problem, however I would recommend re-structuring your approach and instead launching a new Activity which contains the CreateListFragment when the FAB is pressed. Doing so would result in easier to maintain code which is also easier to read and would be best practice. It would also mean that the user can press their back button and navigate back to ListActivity/ListFragment without you needing to manually handle Fragment back stacks.
I have a gridview that shows a list of images, and I implemented choice mode listener for this gridview. The problem is, when I press long click to select set of images, they are not highlighted..
item_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
android:id="#+id/photo"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:contentDescription="#string/media_thumbnail"/>
fragment_photos.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">
<!-- Empty View -->
<RelativeLayout
android:id="#+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<ImageView
android:id="#+id/download_arrow"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_centerInParent="true"
android:contentDescription="#string/downloads"
android:src="#drawable/ic_photo"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/download_arrow"
android:layout_centerInParent="true"
android:layout_marginLeft="32dp"
android:layout_marginRight="32dp"
android:gravity="center"
android:text="#string/no_media"/>
</RelativeLayout>
<!-- Photos List -->
<GridView
android:id="#+id/list"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:paddingBottom="5dp"
android:choiceMode="multipleChoiceModal"
android:paddingTop="5dp"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp"
android:visibility="gone"/>
</RelativeLayout>
PhotosFragment.java
public class PhotosFragment extends Fragment
{
#Bind (R.id.list)
GridView mGridView;
private MediaGridAdapter mAdapter;
private ArrayList<File> mFiles;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_media, container, false);
ButterKnife.bind(this, view);
mGridView.setMultiChoiceModeListener(new MultiChoiceModeListener());
// set adapter and fetch files code ....
return view;
}
}
There is no magic highlight effect, you have to implement it yourself, example would be setting a foreground drawable which is a semi transparent gray.
I'm using this library for the fab implementation.
As you can see in this video, the fab position is changing when the fragment loads.
After debugging it, I found that the listview "setAdapter()" method causes the position change.
I don't have a clue why it's happening..
My layout:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="#style/AppTheme.ActionBar" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/toolbar">
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/sad_face"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/no_leagues" />
</LinearLayout>
</FrameLayout>
<com.melnykov.fab.FloatingActionButton
android:id="#+id/fab_new_league"
android:src="#drawable/ic_action_add"
app:fab_colorNormal="#color/orange"
app:fab_colorPressed="#color/redDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignBottom="#id/toolbar"
android:layout_marginBottom="-28dp"
android:layout_marginRight="28dp"
android:elevation="8dp"/>
</RelativeLayout>
My fragment
public class LeagueListFragment extends MyFragment {
#InjectView(android.R.id.list) ListView mListView;
#InjectView(android.R.id.empty) LinearLayout mEmpty;
public static Fragment newInstance() {
return new LeagueListFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_league_list, container, false);
ButterKnife.inject(this, view);
// Fetch league list and set up adapter
List<League> list = League.getAll();
mAdapter = new LeagueAdapter(getActivity(), list);
// Set up ListView
mListView.setEmptyView(mEmpty);
mListView.setDivider(new ColorDrawable(getResources().getColor(R.color.gray)));
mListView.setDividerHeight(2);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(this);
return view;
}
}
Margin changes in the runtime on pre-Lollipop because shadow mustn't be taken into account when margins are set.
Try to disable the shadow by :
fab:fab_shadow="false"
Fixing the issue is not expected for now.. (See makovkastar answer)
I have the follwing layout:
<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" >
<View
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:id="#+id/bottomNav"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username: " />
</LinearLayout>
Programatically I'm replacing the view "content" with my Fragment:
View view = inflater.inflate(R.layout.kwiz_game, container, false);
contentView = view.findViewById(R.id.content);
currentFragment = new KwizCardBackFragment(android.R.drawable.btn_plus);
getFragmentManager().beginTransaction().replace(R.id.content,
currentFragment);
However the fragment is taking all the space and the Layout with the TextView is not shown.
I also tried to use RelativeLayouts with alignParentBottom=true and other stuff...
View of the Fragment which replaces the content:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_kwiz_item" >
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:scaleType="centerCrop" />
</RelativeLayout>
OnCreateView of the fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_card_back, container,
false);
ImageView imageView = (ImageView) view.findViewById(R.id.image);
if (drawable != null) {
imageView.setImageDrawable(drawable);
} else {
imageView.setBackgroundResource(drawableId);
}
return view;
}
After hours of debugging I finally found the mistake... Some of my layouts had views with the id "content". I thought when I look for R.id.content that the "nearest" element will be used... that's not the case!
Thanks anyone!
I modified your layout a little bit and this seems to achieve what you want:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_alignParentTop="true"
android:layout_above="#+id/bottomNav" />
<LinearLayout
android:id="#+id/bottomNav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Username: " />
</LinearLayout>
</RelativeLayout>
And a small side note, I see you used fill_parent in your layout, but that's deprecated since API level 8, so you should use match_parent instead :)
Hope this helps, cheers!
You should use FrameLayout as your fragment container, and put (and then replace) your fragments into that FrameLayout container.