Introduction
- This series is going to be where I put all my Android notes. As I learn something new about Android development I will put in this tutorial series
GitHub code
Video Version
What we are going to do
- So in this tutorial I am going to show how we can have different layouts for our app depending on the screen size. Which ultimately means that the app will have one view for the vertical position and another for the horizontal position.
- If you are interested in reading more about this subject, you can read the official documentation, HERE
By the end of this tutorial we will be able to see how we can take these two views:
- And then once our app turns to the horizontal view, it will display this view:
SlidingPaneLayout
- The
SlidingPaneLayout
class is what does all the heavy lifting for us. It is what allows the app to seamlessly transition from one view to another. To use it, we must wrap it around the classes that we want to display like so: ```
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:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="280dp"
android:layout_gravity="start"
android:layout_height="match_parent"
tools:context=".fragments.MainFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:layout_marginBottom="100dp"
android:contentDescription="add new calf"
android:src="@drawable/ic_add_black_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/recyclerview"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/detail_container"
android:layout_width="300dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:name="com.elliottsoftware.calftracker2.fragments.NewCalfFragment" />
- As you can see from the XML file above we wrap everything we want to display in the `<SlidingPaneLayout>` tag. Doing so means a few things: **1)overlaping**, if there is no width to display child views,in our case the `FragmentContainerView` and `ConstraintLayout` then they will overlap each other. Which will give us the ability to swipe between those views. If we swipe from one side of the screen to the other we will be able to navigate between whatever is nested inside of `SlidingPaneLayout`.**2)width**, the `layout_width` of the child views is what determines when we are able to see the combined views. Notice from the XML above the combined width is `580dp`, meaning the combined view will only show if the width of the screen is a minimum of 580dp. In general we want the combined total to be less than 600dp if the primary device our app is running on is a phone. Another important attribute to point out is, `android:layout_weight="1"`, which works simular to how it works inside of the LinearLayout. Read more about the `layout_weight`, [HERE](https://developer.android.com/develop/ui/views/layout/linear#Weight). Since only on child has layout_weight="1" meaning if the size is greater than 580 the child with the layout_weight="1" will expand to fill the rest of the space.
###Nested Fragment
- to reuse a fragment we use the `FragmentContainerView` class, which is a layout class specifically designed to hold fragments. Notice that we specified the `android:name` attribute, when this is done inside of the FragmentContainerView 3 things will happen
- **1)** Creates a new instance of the Fragment
- **2)** Calls Fragment.onInflate (inflates the view)
- **3)** executes a FragmentTransaction to add the Fragment to the appropriate FragmentManager
###Detecting orientation changes
- There were some parts of my view that I did not want to show when the orientation changed to horizontal. So to hide certain views we have to detect orientation changes. To do so place this code inside of the `onViewCreated()` method:
val orientation:Int = resources.configuration.orientation
if(orientation == Configuration.ORIENTATION_LANDSCAPE){
//code to hide
fabButton.hide()
}
- I am first finding the orientation and then hiding the View. Most views can be hidden from the user by getting a reference to them first and then calling the `hide()` method.
###Weird bugs I encountered in Horizontal View
- **1)** The first bug I encountered was with `EditText`. When in a horizontal configuration, anytime a user would click on a EditText view a massive white keyboard would appear and cover everthing (the soft keyboard). To fix this I applied the `android:imeOptions="flagNoExtractUi"` to every EditText in my XML files. This tells the Android system to not show the full keyboard during text inputs. This allows for a less jarring ui when a EditText is full screen
- **2)** The second bug was scrolling effect on the EditText view stopped working. Meaning that the user could not see what they where typing. To fix this I wrapped a ScrollView around a LinearLayout like so:
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout>
</LinearLayout>
- The `ScrollView` allows the user to scroll to the EditText view if it can not be seen while typing.
###Programmatically swap out the detail pane
- tutorials about this will be coming in my next post
###Conclusion
- Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on [Twitter](https://twitter.com/AndroidTristan).
Top comments (0)