The following code is from CameraXBasic project Github
The CameraFragment.kt loads fragment_camera.xml first, then loads camera_ui_container.xml.
I find it strange that CameraXBasic project doesn't merge the two layout files both fragment_camera.xml and camera_ui_container.xml into one, and CameraFragment.kt only loads the merged layout file.
CameraFragment.kt
class CameraFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? =
inflater.inflate(R.layout.fragment_camera, container, false)
private fun updateCameraUi() {
// Remove previous UI if any
container.findViewById<ConstraintLayout>(R.id.camera_ui_container)?.let {
container.removeView(it)
}
// Inflate a new view containing all UI for controlling the camera
val controls = View.inflate(requireContext(), R.layout.camera_ui_container, container)
..
}
}
fragment_camera.xml
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/camera_container"
android:background="#android:color/black"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="#+id/view_finder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
camera_ui_container.xml
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/camera_ui_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Camera control and gallery buttons -->
<ImageButton
android:id="#+id/camera_switch_button"
android:layout_width="#dimen/round_button_medium"
android:layout_height="#dimen/round_button_medium"
android:layout_marginBottom="#dimen/margin_xlarge"
android:layout_marginLeft="#dimen/margin_small"
android:padding="#dimen/spacing_small"
android:scaleType="fitCenter"
android:background="#android:color/transparent"
app:srcCompat="#drawable/ic_switch"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:contentDescription="#string/switch_camera_button_alt" />
<ImageButton
android:id="#+id/camera_capture_button"
android:layout_width="#dimen/round_button_large"
android:layout_height="#dimen/round_button_large"
android:layout_marginBottom="#dimen/shutter_button_margin"
android:scaleType="fitCenter"
android:background="#drawable/ic_shutter"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:contentDescription="#string/capture_button_alt" />
<ImageButton
android:id="#+id/photo_view_button"
android:layout_width="#dimen/round_button_medium"
android:layout_height="#dimen/round_button_medium"
android:layout_marginBottom="#dimen/margin_xlarge"
android:layout_marginRight="#dimen/margin_small"
android:padding="#dimen/spacing_large"
android:scaleType="fitCenter"
android:background="#drawable/ic_outer_circle"
app:srcCompat="#drawable/ic_photo"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:contentDescription="#string/gallery_button_alt" />
</androidx.constraintlayout.widget.ConstraintLayout>
Added Content
I test the merged layout (Normal and landsacpe), it works well, and I think the speed of both original and mine are almost the same.
CameraFragment.kt (New)
private fun updateCameraUi() {
// Remove previous UI if any
// container.findViewById<ConstraintLayout>(R.id.camera_ui_container)?.let {
// container.removeView(it)
//}
// Inflate a new view containing all UI for controlling the camera
//val controls = View.inflate(requireContext(), R.layout.camera_ui_container, container)
// Listener for button used to capture photo
...
}
fragment_camera.xml (New)
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/camera_container"
android:background="#android:color/black"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="#+id/view_finder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Camera control and gallery buttons -->
<ImageButton
android:id="#+id/camera_switch_button"
android:layout_width="#dimen/round_button_medium"
android:layout_height="#dimen/round_button_medium"
android:layout_marginBottom="#dimen/margin_xlarge"
android:layout_marginLeft="#dimen/margin_small"
android:padding="#dimen/spacing_small"
android:scaleType="fitCenter"
android:background="#android:color/transparent"
app:srcCompat="#drawable/ic_switch"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:contentDescription="#string/switch_camera_button_alt" />
<ImageButton
android:id="#+id/camera_capture_button"
android:layout_width="#dimen/round_button_large"
android:layout_height="#dimen/round_button_large"
android:layout_marginBottom="#dimen/shutter_button_margin"
android:scaleType="fitCenter"
android:background="#drawable/ic_shutter"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:contentDescription="#string/capture_button_alt" />
<ImageButton
android:id="#+id/photo_view_button"
android:layout_width="#dimen/round_button_medium"
android:layout_height="#dimen/round_button_medium"
android:layout_marginBottom="#dimen/margin_xlarge"
android:layout_marginRight="#dimen/margin_small"
android:padding="#dimen/spacing_large"
android:scaleType="fitCenter"
android:background="#drawable/ic_outer_circle"
app:srcCompat="#drawable/ic_photo"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:contentDescription="#string/gallery_button_alt" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_camera.xml (New land)
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/camera_container"
android:background="#android:color/black"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="#+id/view_finder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Camera control and gallery buttons -->
<ImageButton
android:id="#id/camera_switch_button"
android:layout_width="#dimen/round_button_medium"
android:layout_height="#dimen/round_button_medium"
android:layout_marginRight="#dimen/margin_xlarge"
android:layout_marginBottom="#dimen/margin_small"
android:padding="#dimen/spacing_small"
android:scaleType="fitXY"
android:background="#android:color/transparent"
app:srcCompat="#drawable/ic_switch"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:contentDescription="#string/gallery_button_alt" />
<ImageButton
android:id="#id/camera_capture_button"
android:layout_width="#dimen/round_button_large"
android:layout_height="#dimen/round_button_large"
android:layout_marginRight="#dimen/shutter_button_margin"
android:background="#drawable/ic_shutter"
android:contentDescription="#string/capture_button_alt"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#id/photo_view_button"
android:layout_width="#dimen/round_button_medium"
android:layout_height="#dimen/round_button_medium"
android:layout_marginRight="#dimen/margin_xlarge"
android:layout_marginTop="#dimen/margin_small"
android:padding="#dimen/spacing_large"
android:scaleType="fitXY"
android:background="#drawable/ic_outer_circle"
app:srcCompat="#drawable/ic_photo"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="#string/switch_camera_button_alt" />
</androidx.constraintlayout.widget.ConstraintLayout>
Their idea is to recreate UI every time the configuration changes, while the TextureView persists.
Did you noticed that there are two XML camera_ui_container.xml files one for portrait and one for landscape orientation to achieve different UI on rotation. and the line
// Remove previous UI if any
container.findViewById(R.id.camera_ui_container)?.let
{
container.removeView(it)
}
is actually doing the recreation part of Camera UI #Alex Cohn is right, on same point.
You can do it with single layout if you are only handling single orientation.
Related
The items in my RecyclerView Grid are stretched automatically if the left item is shorter and the right item is taller or vice versa (2 grid spans) because I want to use layout_height="wrap_content". How to keep that left item from being stretched automatically? I still want to use the GridLayout style because in my case it is not suitable if using StaggeredGridLayout (because it is more suitable for photo galleries).
<androidx.coordinatorlayout.widget.CoordinatorLayout
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:background="#color/very_light_gray"
android:paddingBottom="61dp"
tools:context="Fragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_explore_buyer_outlet"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
android:overScrollMode="ifContentScrolls"
android:paddingEnd="#dimen/_20sdp"
android:paddingBottom="28dp"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:spanCount="2"
tools:ignore="RtlSymmetry"
tools:itemCount="18"
tools:listitem="#layout/item_grid" />
</androidx.constraintlayout.widget.ConstraintLayout
</androidx.coordinatorlayout.widget.CoordinatorLayout>
item_grid.xml
<androidx.cardview.widget.CardView
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="177dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_14sdp"
android:layout_marginTop="#dimen/_14sdp"
android:layout_marginEnd="#dimen/_minus18sdp"
android:layout_marginBottom="-7dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="14dp"
app:cardElevation="1dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_item_outlet_buyer_photo"
android:layout_width="match_parent"
android:layout_height="112dp"
android:importantForAccessibility="no"
android:scaleType="centerCrop"
android:src="#drawable/outlet10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tv_item_outlet_buyer_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="9dp"
android:background="#drawable/outlet_buyer_status_open_label"
android:fontFamily="#font/notosansjp_medium"
android:gravity="center"
android:includeFontPadding="false"
android:paddingHorizontal="8dp"
android:paddingTop="3dp"
android:paddingBottom="3.75dp"
android:textColor="#color/white"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="#+id/iv_item_outlet_buyer_photo"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="SmallSp"
tools:text="Open" />
<TextView
android:id="#+id/tv_item_outlet_buyer_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10.5dp"
android:fontFamily="#font/notosansjp_bold"
android:includeFontPadding="false"
android:lineSpacingExtra="1.5dp"
android:paddingStart="15dp"
android:paddingEnd="#dimen/_17sdp"
android:paddingBottom="2dp"
android:textColor="#color/dark_gray"
android:textSize="#dimen/_10ssp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/iv_item_outlet_buyer_photo"
tools:text="Guttenburg, Alazka" />
<ImageView
android:id="#+id/iv_item_outlet_buyer_dotted_line"
android:layout_width="0dp"
android:layout_height="5dp"
android:layout_marginTop="5dp"
android:importantForAccessibility="no"
android:layerType="software"
android:paddingStart="16dp"
android:paddingEnd="15dp"
android:src="#drawable/dotted_shape"
app:layout_constraintEnd_toEndOf="#+id/tv_item_outlet_buyer_name"
app:layout_constraintStart_toStartOf="#+id/tv_item_outlet_buyer_name"
app:layout_constraintTop_toBottomOf="#+id/tv_item_outlet_buyer_name" />
<TextView
android:id="#+id/tv_item_outlet_buyer_category"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4.5dp"
android:layout_marginBottom="14dp"
android:fontFamily="#font/notosansjp_regular"
android:includeFontPadding="false"
android:lineSpacingExtra="1.5dp"
android:paddingHorizontal="15dp"
android:textColor="#color/dark_gray"
android:textSize="11sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/iv_item_outlet_buyer_dotted_line"
tools:ignore="SmallSp"
tools:text="Food ∙ Drink ∙ Snack" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
I want make my GridLayout like this (edited in Figma):
But I got like this if last textView have constraintBottom_toBottomOf(parent):
And, I got like this if last textView not have constraintBottom_toBottomOf(parent):
What should I do?
You just need to make sure your TextView's layout_height is wrap_content, and give that the black background. The containing layout should be transparent, so when it resizes to fit the grid, the extra space is just "empty". The TextView shouldn't resize with it (and neither should anything else in the item's layout), so the black area stays the same - the extra height is unused.
Here's a quick example
MainFragment.kt
class MainFragment : Fragment(R.layout.fragment_main) {
lateinit var binding: FragmentMainBinding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// fragment_main.xml has a RecyclerView in it with "recycler" for its ID
binding = FragmentMainBinding.bind(view)
with(binding) {
recycler.layoutManager = GridLayoutManager(requireContext(), 2)
recycler.adapter = Adapterino(requireContext())
}
}
private class Adapterino(val context: Context) : RecyclerView.Adapter<Adapterino.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
ItemViewBinding.inflate(LayoutInflater.from(context)).run(::ViewHolder)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// just generating random amounts of text to get some variation
holder.binding.textView.text =
generateSequence { "cats" }.take(Random.nextInt(5, 20)).joinToString(" ")
}
override fun getItemCount(): Int = 20
private class ViewHolder(val binding: ItemViewBinding) : RecyclerView.ViewHolder(binding.root)
}
}
item_view.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="wrap_content"
android:orientation="vertical"
android:padding="8dp"
>
<View
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#color/black"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="240dp"
android:src="#mipmap/ic_launcher"
/>
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black"
android:textColor="#color/white"
android:textSize="20sp"
/>
</LinearLayout>
I tried windowSoftInputMode in manifest nothing worked the views get pushed up when the keyboard is opened I tried different approaches but none of them worked. The recycler view collapses with the edit text but it is below the guide line separator.
Image when keyboard is opened:
Image when the keyboard is not opened:
<androidx.constraintlayout.widget.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="match_parent"
android:background="#color/bg_color_for_screen">
<!--Guide line left-->
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guide_line_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="#dimen/padding_margin_15" />
<!--Guide line right-->
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guide_line_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="#dimen/padding_margin_15" />
<!--Guide line for separating image-->
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guide_line_separator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.17" />
<!--Image for the top header-->
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="#+id/guide_line_separator"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/splash_bg" />
<!--back button image-->
<ImageView
android:id="#+id/step_back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/padding_margin_15"
android:scaleType="centerCrop"
android:src="#mipmap/ic_back_arrow"
android:tint="#color/white"
android:visibility="visible"
app:layout_constraintStart_toStartOf="#id/guide_line_left"
app:layout_constraintTop_toTopOf="parent" />
<!--title for the screen-->
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/padding_margin_10"
android:layout_marginLeft="#dimen/padding_margin_5"
android:layout_marginTop="#dimen/padding_margin_18"
android:fontFamily="#font/nunito_medium"
android:text="#string/blank"
android:textColor="#color/white"
android:textSize="#dimen/text_size_18"
app:layout_constraintStart_toEndOf="#+id/step_back_button"
app:layout_constraintTop_toTopOf="parent" />
<!--edit text for searching by the keyword-->
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/edit_text_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/padding_margin_10"
android:layout_marginTop="#dimen/padding_margin_12"
android:background="#drawable/edit_text_background"
android:drawableStart="#mipmap/ic_search"
android:drawablePadding="#dimen/padding_margin_8"
android:fontFamily="#font/nunito_regular"
android:hint="#string/blank"
android:padding="#dimen/padding_margin_10"
android:textSize="#dimen/text_size_15"
app:layout_constraintEnd_toStartOf="#+id/guide_line_right"
app:layout_constraintStart_toStartOf="#id/guide_line_left"
app:layout_constraintTop_toBottomOf="#+id/label" />
<!--recycler view for the list -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="#dimen/padding_margin_5"
android:layout_marginBottom="#dimen/padding_margin_5"
android:background="#color/transparent"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="#id/guide_line_right"
app:layout_constraintStart_toStartOf="#id/guide_line_left"
app:layout_constraintTop_toBottomOf="#+id/guide_line_separator" />
</androidx.constraintlayout.widget.ConstraintLayout>
Please try to remove this line from rv and then try it.
app:layout_constraintBottom_toTopOf="parent"
Hi I am using single activity over which I have used all fragments. I am developing a screen of gallery fragment in which I am showing slide show with bottom recycler view to slide pages of slide show. The bottom view of gallery recycler is getting hide from bottom navigation bar.
What I have used:- I have added window flag to gallery fragment from main activity backstackChangeListner
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
Here is my gallery fragment view
<data>
<variable
name="viewImageVM"
type="com.geenie.consumer.viewmodel.ViewImageViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:background="#android:color/black"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:weightSum="10">
<!--
this is my slide show view pager for gallery
-->
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.viewpager.widget.ViewPager>
<!--
this is for backward slide in my slide show
-->
<ImageView
android:id="#+id/start"
android:layout_width="35dp"
android:layout_height="0dp"
android:background="#BF3e434c"
android:elevation="#dimen/margin_large"
android:onClick='#{(v)->viewImageVM.switchToComponent("Backward")}'
android:padding="10dp"
android:src="#drawable/ic_back_arrow_gray"
android:tint="#color/gray"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="#+id/bottomRecycler"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/bottomRecycler" />
<!--
this is bottom icons of image for selecting the image
-->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/bottomRecycler"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#android:color/transparent"
android:paddingStart="5dp"
app:layout_constraintBottom_toBottomOf="parent" />
<!--
this is for forward slide in my slide show
-->
<ImageView
android:id="#+id/end"
android:layout_width="35dp"
android:layout_height="0dp"
android:background="#BF3e434c"
android:elevation="#dimen/margin_large"
android:onClick='#{(v)->viewImageVM.switchToComponent("Forward")}'
android:padding="10dp"
android:rotation="180"
android:src="#drawable/ic_back_arrow_gray"
android:tint="#color/gray"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="#+id/bottomRecycler"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/bottomRecycler" />
<!--
this is my custom toolbar
-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="5dp"
android:scaleType="centerInside"
app:layout_constraintBottom_toBottomOf="parent"
android:onClick='#{(v)->viewImageVM.switchToComponent("Back")}'
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:tint="#color/gray"
app:srcCompat="#drawable/ic_back_arrow_gray" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="35dp"
android:padding="#dimen/padding_small"
android:tint="#color/gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:visibility="gone"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="#dimen/margin_small"
android:src="#drawable/trash_white"
android:padding="3dp"
android:textColor="#android:color/darker_gray"
android:textSize="#dimen/txt_normal"
android:textStyle="bold"
app:fontFamily="#font/sfprodisplay_bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I have used android:fitsSystemWindows="true" attribute in recyclerview which is getting hidden by navigation bar still no effect is getting seen in that my current screen. Please see screenshot of what I have achieved till now. Please help me I have used android:fitsSystemWindows="true" earlier also which worked fine. Now I am missing somewhere.Any help would be highly appreciated.Thanks
I am struggling to get ConstraintLayout to work for me when I want to refactor common layout code into a separate xml file. I can easily do this with RelativeLayouts but I believe RelativeLayouts are deprecated and we should be using ConstraintLayous now.
I have an app with a screen which has a different layout on portrait and landscape as illustrated in the diagram below.
I have 2 layout files with the same name ("my_layout.xml"), one in "layout" folder and one in "layout-land". Currently i have duplicated all the xml in both the layout files and adjusted the constraints so that in the landscape version the views are placed horizontally.
Portrait version
<androidx.constraintlayout.widget.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">
<!-- OTHER VIEWS 1 -->
<View
android:id="#+id/OtherViews1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- OTHER VIEWS 2 -->
<View
android:id="#+id/OtherViews2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottom="#+id/OtherViews1"
app:layout_constraintBottom_toTopOf="#+id/scrollbar" />
<!-- SCROLL BAR VIEWS -->
<TextView
android:id="#+id/slow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="#+id/scrollbar"
app:layout_constraintBottom_toBottomOf="#+id/scrollbar"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatSeekBar
android:id="#+id/scrollbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
...
app:layout_constraintBottom_toTopOf="#+id/OtherViews3"
app:layout_constraintStart_toEndOf="#+id/slow"
app:layout_constraintEnd_toStartOf="#+id/fast"/>
<TextView
android:id="#+id/fast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="#+id/scrollbar"
app:layout_constraintBottom_toBottomOf="#+id/scrollbar"
app:layout_constraintStartEnd_toEndOf="parent" />
<!-- OTHER VIEWS 3 -->
<View
android:id="#+id/OtherViews3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Landscape version
<androidx.constraintlayout.widget.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">
<!-- OTHER VIEWS 1 -->
<View
android:id="#+id/OtherViews1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- OTHER VIEWS 2 -->
<View
android:id="#+id/OtherViews2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottom="#+id/OtherViews1"
app:layout_constraintBottom_toBottomOf="parent" />
<!-- SCROLL BAR VIEWS -->
<TextView
android:id="#+id/slow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintStart_toEndOf="#+id/OtherViews2"
app:layout_constraintTop_toTopOf="#+id/scrollbar"
app:layout_constraintBottom_toBottomOf="#+id/scrollbar"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.appcompat.widget.AppCompatSeekBar
android:id="#+id/scrollbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
...
app:layout_constraintBottom_toTopOf="#+id/OtherViews3"
app:layout_constraintStart_toEndOf="#+id/slow"
app:layout_constraintEnd_toStartOf="#+id/fast"/>
<TextView
android:id="#+id/fast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="#+id/scrollbar"
app:layout_constraintBottom_toBottomOf="#+id/scrollbar"
app:layout_constraintStartEnd_toEndOf="parent" />
<!-- OTHER VIEWS 3 -->
<View
android:id="#+id/OtherViews3"
android:layout_width="wrap_content"
android:layout_height="wrap_content
app:layout_constraintStart_toEndOf="#+id/OtherViews2""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The xml for the "Slow" textbox, the scrollbar and the "Fast" textbox is duplicated in both files. I would like to move the layout for these 3 elements into a separate file and reference it in both "my_layout.xml" files so its more reusable and no duplication across layout files. I want to keep my hierarchy flat (otherwise i would just use RelativeLayouts). I do not know how to specify the constraints of the new reusable xml layout file for the scrollbar UI.
Portrait version reusing the scrollbar layout
<androidx.constraintlayout.widget.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">
<!-- OTHER VIEWS 1 -->
<View
android:id="#+id/OtherViews1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- OTHER VIEWS 2 -->
<View
android:id="#+id/OtherViews2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottom="#+id/OtherViews1"
app:layout_constraintBottom_toTopOf="#+id/scrollbar" />
<include
layout="#layout/scrollbar
app:layout_constraintBottom_toTopOf="#+id/OtherViews3"
app:layout_constraintStart_toStartOf="parent" />
<!-- OTHER VIEWS 3 -->
<View
android:id="#+id/OtherViews3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Reusable scrollbar layout
<androidx.constraintlayout.widget.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="wrap_content"
android:layout_height="wrap_content">
<!-- SCROLL BAR VIEWS -->
<TextView
android:id="#+id/slow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="#+id/scrollbar"
app:layout_constraintBottom_toBottomOf="#+id/scrollbar"
app:layout_constraintStart_toStartOf="parent"/> ******************
<androidx.appcompat.widget.AppCompatSeekBar
android:id="#+id/scrollbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
...
app:layout_constraintBottom_toTopOf="#+id/OtherViews3" ******************
app:layout_constraintStart_toEndOf="#+id/slow"
app:layout_constraintEnd_toStartOf="#+id/fast"/>
<TextView
android:id="#+id/fast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:layout_constraintTop_toTopOf="#+id/scrollbar"
app:layout_constraintBottom_toBottomOf="#+id/scrollbar"
app:layout_constraintStartEnd_toEndOf="parent" /> ******************
</androidx.constraintlayout.widget.ConstraintLayout>
I do not know what to put for the lines marked with ****. If I specify that the "slow" textbox starts at the start of the parent, that will not work for the landscape version. I would like this scrollbar layout to just indicate the slow is to the left, the scrollbar in the middle (taking up all remaining space) and the fast textbox is on the right. How do i do that using Constraint Layout? Also how do i center all 3 views vertically?
RelativeLayout is so much easier, as i would say the slow textbox is alignedParentLeft, the fast is alignedParentRight and the scrollbar is to the right of the slow textbox and to the left of the fast textbox. Finally i would say all 3 views are centered vertically in the parent.
A view in the included layout cannot refer to a view in the layout file in which it is included. You can still use an included layout with a different approach.
Look at the included layout with the fast/slow text and the seek bar as a self-enclosed entity - something like the following:
scrollbar.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/slow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Slow"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatSeekBar
android:id="#+id/scrollbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="#+id/slow"
app:layout_constraintEnd_toStartOf="#+id/fast"
app:layout_constraintStart_toEndOf="#+id/slow"
app:layout_constraintTop_toTopOf="#+id/slow" />
<TextView
android:id="#+id/fast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fast"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can now include this layout in layouts for portrait and landscape orientation:
activity_main.xml (portrait)
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<TextView
android:id="#+id/OtherViews1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#FFCCCCCC"
android:gravity="center"
android:text="OtherViews1"
app:layout_constraintBottom_toTopOf="#+id/OtherViews2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_weight="1" />
<TextView
android:id="#+id/OtherViews2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:background="#FFCCCCCC"
android:gravity="center"
android:text="OtherViews2"
app:layout_constraintBottom_toTopOf="#+id/scrollbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottom="#+id/OtherViews1"
app:layout_constraintTop_toBottomOf="#+id/OtherViews1"
app:layout_constraintVertical_weight="4" />
<include
layout="#layout/scrollbar"
android:id="#+id/scrollbar"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/OtherViews3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/OtherViews2"
app:layout_constraintVertical_weight="0.5" />
<TextView
android:id="#+id/OtherViews3"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="24dp"
android:background="#FFCCCCCC"
android:gravity="center"
android:text="OtherViews3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/scrollbar"
app:layout_constraintVertical_weight="1" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_main.xml (landscape)
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<TextView
android:id="#+id/OtherViews1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#FFCCCCCC"
android:gravity="center"
android:text="OtherViews1"
app:layout_constraintBottom_toTopOf="#+id/OtherViews2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_weight="1" />
<TextView
android:id="#+id/OtherViews2"
android:layout_width="342dp"
android:layout_height="0dp"
android:layout_marginTop="24dp"
android:background="#FFCCCCCC"
android:gravity="center"
android:text="OtherViews2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottom="#+id/OtherViews1"
app:layout_constraintTop_toBottomOf="#+id/OtherViews1"
app:layout_constraintVertical_weight="8" />
<include
android:id="#+id/scrollbar"
layout="#layout/scrollbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toTopOf="#+id/OtherViews3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#+id/OtherViews3" />
<!-- OTHER VIEWS 3 -->
<TextView
android:id="#+id/OtherViews3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:background="#FFCCCCCC"
android:gravity="center"
android:text="OtherViews3"
app:layout_constraintBottom_toBottomOf="#+id/OtherViews2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/OtherViews2" />
</androidx.constraintlayout.widget.ConstraintLayout>
The included layout file can be treated, in terms of constraints and size, like its own widget. See Re-using layouts with <include/>.
I have following layout includes a NestedScrollView(it has a RecyclerView inside) :
<android.support.constraint.motion.MotionLayout
android:id="#+id/details_motion"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="#xml/scene_show_details">
<ImageView
android:id="#+id/details_backdrop"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:imageUrl="#{movie.backdropPath}"
tools:ignore="ContentDescription" />
<android.support.v7.widget.AppCompatImageView
android:id="#+id/details_poster"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#drawable/placeholder"
android:scaleType="centerCrop"
android:transformPivotX="0px"
android:transformPivotY="0px"
android:transitionName="#string/view_name_header_image"
app:imageUrl="#{movie.posterPath}" />
<android.support.v7.widget.Toolbar
android:id="#+id/details_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:theme="#style/Toolbar" />
<android.support.v4.widget.NestedScrollView
android:id="#+id/details_rv"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/window_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/details_appbar_background">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
style="#style/TmdbMargin.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/padding_normal"
android:text="#{#string/release_date(movie.releaseDate)}" />
<TextView
style="#style/TmdbMargin.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{#string/rating(movie.voteAverage)}" />
<TextView
style="#style/TmdbMargin.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/summary" />
<TextView
android:id="#+id/summary"
style="#style/TmdbMargin.Body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{movie.overview}" />
<include
layout="#layout/trailers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/padding_normal"
android:layout_marginTop="#dimen/padding_large"
app:vm="#{vm}"
tools:ignore="RtlHardcoded" />
<TextView
style="#style/TmdbMargin.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/padding_normal"
android:text="#string/cast"
app:visibleGone="#{vm.isCastVisible}" />
<android.support.v7.widget.RecyclerView
android:id="#+id/cast_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="12dp" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.constraint.motion.MotionLayout>
When I rotate the device (for instance when I am in the middle of RecyclerView list), I want to scroll to top of NestedScrollView. I tried :
nestedScrollView.fullScroll(View.FOCUS_UP);
nestedScrollView.scrollTo(0,0);
But none of them worked in my case. Could be any solution for me?
Source code can be found at : https://github.com/Ali-Rezaei/TMDb-Paging
I downloaded your app, problem is a while you trying to set scrollTo(0,0) or through fullScroll(View.FOCUS_UP), your list has not been initialized / rendered, list is empty when you calling operation scroll to top. Easy workaround is delayed your scroll operation (not so perfect way):
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Your code ....
// ....
nestedScrollView = view.findViewById<NestedScrollView>(R.id.details_rv)
nestedScrollView.postDelayed({
nestedScrollView.scrollTo(0, 0)
}, 100)
}
While searched solution found a lot of great animations. You are MotionLayout monster :)