700 likes | 927 Views
Linear Layout, Screen Support, and Events. Linear Layout. Supports 2 orientations: Horizontal Vertical I often get confused with how each orientation is laid out. Horizontal Orientation. One row, many columns Items placed beside each other. # # # # # # # # # #. Vertical Orientation.
E N D
Linear Layout • Supports 2 orientations: • Horizontal • Vertical • I often get confused with how each orientation is laid out.
Horizontal Orientation • One row, many columns • Items placed beside each other # # # # # # # # # #
Vertical Orientation • One column, many rows • Items stacked on top of each other # # # # # #
Gravity • Two types of Gravity in Android • gravity • layout_gravity • A lot of people get confused with the appropriate usage of each one.
android:gravity • Positions the contents of the view (what is inside the view) • Has several values: • top • bottom • left • right • center (horizontal and vertical) • center_vertical • center_horizontal
android:gravity • Use bit masking to combine multiple values android:gravity="center_horizontal|bottom“ android:gravity=“top|bottom” android:gravity=“top|right”
android:layout_gravity • Positions the view with respect to its parent • Supports same values as android:gravity • Not all ViewGroups support this attribute.
gravity vs. layout_gravity • I still don’t understand the difference… • Using gravity on a ViewGroup will position all of its children a specific way. Using a LinearLayout as the root view to encapsulate everything. The LinearLayout has an attribute of gravity with a value equal to center. (That is why all the button are centered in the screen.)
gravity vs. layout_gravity • Using layout_gravity, a child can override the gravity set on it by its parent. Using a LinearLayout as the root view to encapsulate everything. The blue button has an attribute of layout_gravity with a value equal to right. (That is why all the button are centered in the screen, except the blue button which is on the right.)
What does this render? <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=“match_parent" android:layout_height="match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> </LinearLayout> </LinearLayout>
What does this render? <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=“match_parent" android:layout_height="match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> </LinearLayout> </LinearLayout>
Why isn’t the content centered? <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=“match_parent" android:layout_height="match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> </LinearLayout> </LinearLayout>
What is the width of the LinearLayout? <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=“match_parent" android:layout_height="match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> </LinearLayout> </LinearLayout>
What is the width of the LinearLayout? <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=“match_parent" android:layout_height="match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> </LinearLayout> </LinearLayout> Because the parent LinearLayout has width “wrap_content”, it’s essentially “hugging” the two views inside and so they have no space to center themselves in.
Adjust LinearLayout Width <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=“match_parent" android:layout_height="match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width=“match_parent" android:layout_height="wrap_content" android:gravity="center" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" /> </LinearLayout> </LinearLayout> A possible fix is to make the linearlayout as wide as its parent so use match_parent
Take 2: What does this render? <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=“match_parent" android:layout_height=“match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width=“match_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:text="@string/hello" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:src="@drawable/icon" /> </LinearLayout> </LinearLayout>
Take 2: What does this render? <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=“match_parent" android:layout_height=“match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width=“match_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:text="@string/hello" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:src="@drawable/icon" /> </LinearLayout> </LinearLayout> Okay so my my parent fills the entire width and I tell the TextView to position itself with respect to its parent on the left, and I tell the ImageView to position itself with respect to its parent on the right, but how come it doesn’t work?
LinearLayouts and layout_gravity • Depending on the orientation of the LinearLayout, the LinearLayout’s children can only use certain values for layout_gravity.
layout_gravity with horizontal orientation • For a horizontal Linear Layout the following values make sense: • top • center • Bottom • That is because the children of a horizontal Linear Layout are laid out horizontally one after the other. • With horizontal orientation, the only thing can be controlled using the android:layout_gravity is how a child view is positioned vertically.
layout_gravity with vertical orientaiton • For a vertical Linear Layout the following values make sense: • left • center • Right • That is because the children of a vertical Linear Layout are laid out vertically one below the other. • With vertical orientation, the only thing can be controlled using the android:layout_gravity is how a child view is positioned horizontally.
layout_weight • Attribute only works for LinearLayout • Indicates how much of the extra space in the LinearLayout will be allocated to the view associated with this attribute.
layout_weight • The size of the View will be determined based on the relation of all sibling’s weights to each other. • If, for example, all views define the same weight, then the available space will be distributed equally among them.
layout_weight • Which axis (width or height) should be affected can be controlled by setting the respective size to a value of 0dp. • Weights don’t have to add up to 1, although it’s common to distribute layout weight over all children as fractions of 1 (percentage semantics). • The relation between all weights is what matters.
Problem • I have 4 Views whose width I want to be equally distributed inside their parent. • I want this to work on any device, and I don’t want to calculate the width each time the app runs.
layout_weight to the rescue • Using layout_weight we can assign an equal weight to each child view and at runtime the LinearLayout will equally distribute any remaining space to the children.
layout_weight to the rescue <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/pink" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:background="#00F" > <View android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight=".25" android:background="#0F0"/> <View android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight=".25" android:background="#F00"/> <View android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight=".25" android:background="#FC0"/> <View android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight=".25" android:background="#FF0"/> </LinearLayout>
Screen Support Key Terms • Screen Density • Resolution • Orientation • Density-independent pixel
Screen Density • The quantity of pixels within a physical area of the screen. • Usually referred to as dpi • Android groups screen densities by: low, medium, high, extra high • A low density screen has fewer pixels within a given physical area than a “normal” or “high” density screen.
Resolution • The total number of pixels on a screen • Use the resolution to manage layouts for your application based on available screen width/height. • Create layouts that are configured for • Smallest width • Available screen width • Available screen height
Resolution • If you want to create layouts for specific resolutions, find more information here.
Orientation • The orientation of the screen from the user’s point of view • Either landscape or portrait • You can create specific layouts catered to your devices orientation
Density Independent Pixel (dp) • A virtual pixel unit • Should be used for defining UI layout that can be reused for multiple screen sizes.
How big is a dp? • See my Android Display Metric Cheat Sheet.
Creating an emulator for a specific device • Use this article
Handling UI Events Topics • Overview of UI Events • Implementing UI Event Listeners
UI Events • Key • Touch • Click • Long Click • Focus Change • Track ball • Drag and Drop
Key Events Called when a hardware key is dispatched to focuseda view. Event Listener Interface: View.OnKeyListener Callback Method: onKey()
Touch Events This is called when the user performs an action qualified as a touch event: • Press • Release • Movement (within the bounds of a view). Event Listener Interface: View.OnTouchListener Callback Method: onTouch()
onTouch(View v, MotionEvent event) • Takes 2 parameters • Returnstrue if the listener consumed the event, false otherwise.
MotionEvent • Used to report movement for • Mouse • Pen • Finger (Touch) • Trackball
MotionEvent for touch • Contains data about “pointers” aka active touch points on the device’s screen. • For each pointer you can receive • X/Y coordinates • Size • Pressure • Value describing what kind of motion occurred.
MotionEvent for single pointer • getAction() – return the action being performed (action_down/move/up/cancel). • getX() - returns the X coordinate of this event for a single pointer. • getY() - returns the Y coordinate of this event for the given pointer
getAction() • ACTION_DOWN - A touch gesture has started. • ACTION_MOVE - A change has occurred between touch down and release. • ACTION_UP – A touch gesture has finished. • ACTION_CANCEL – A touch gesture has been aborted.
@Override publicbooleanonTouchEvent(MotionEventev){ finalint action =ev.getAction(); switch(action){ caseMotionEvent.ACTION_DOWN:{ finalfloat x =ev.getX(); finalfloat y =ev.getY(); // Remember where we started mLastTouchX= x; mLastTouchY= y; break; } caseMotionEvent.ACTION_MOVE:{ finalfloat x =ev.getX(); finalfloat y =ev.getY(); // Calculate the distance moved finalfloat dx = x -mLastTouchX; finalfloatdy= y -mLastTouchY; // Move the object mPosX+= dx; mPosY+=dy; // Remember this touch position for the next move event mLastTouchX= x; mLastTouchY= y; // Invalidate to request a redraw invalidate(); break; } } returntrue; }
MotionEvent for multiple pointers The MotionEvent class provides many methods to query the position and other properties of pointers: • getX(int) – returns X pos for given pointer index. • getY(int) – returns Y pos for given pointer index. • getPointerCount() – The number of pointers for this event
MotionEvent for multiple pointers • getPointerId(int) – pointer id associated with the pointer index for this event • findPointerIndex(int) – given a pointer id, find the index of its data.
New getAction() values • ACTION_POINTER_DOWN – fired when a secondary pointer goes down. • ACTION_POINTER_UP – fired when a secondary pointer goes up.
Pointer index • Each pointer index corresponds to a finger for the event. • The pointer index ranges from 0 to one less than the returned value of getPointerCount(). • The order in which individual pointers appear is undefined; therefore you can’t rely on the pointer index to map to the same finger across touch events.