Android: Creating a custom container-view - java

I'm trying to create a custom view (or better, layout) in android, that serves as a container for 2 child views (Think of it as a bar that separates 2 containers vertically, that can be swiped up and down).
I'd like to use it like a layout in xml, so that you can nest any views in it.
I thought of something like that:
<view class="at.calista.quatscha.views.SwipebarLayout"
android:id="#+id/sbl"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Top View -->
<Button android:text="Top" android:id="#+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
<!-- Bottom View -->
<Button android:text="Bottom" android:id="#+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</view>
This xml should give me the swipeable bar between the two buttons.
However, I don't know how to accomplish this, I'm extending LinearLayout atm, but how do I tell my children how to position themselves?

instead of
<view class="at.calista.quatscha.views.SwipebarLayout"
android:id="#+id/sbl"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
you can use
<at.calista.quatscha.views.SwipebarLayout
android:id="#+id/sbl"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
If your SwipebarLayout class extends LinearLayout it will behave exactly same way as if you would have LinearLayout tag in your code instead and you can position the children exactly same way you would with LinearLayout. Of course if you have overridden some methods from LinearLayout then the functionality is different from that part.

Related

Making a background image move in Android

I am working on a simple project and i wanted to know what or how is the best way to make your background image appear moving or move , i have this clouds that i want to move infinitely ? any help will be appreciated.
A <FrameLayout ...> (in the layout xml) draws its children one on top of another.
So
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
< the background view />
< the informative view />
</FrameLayout>
should do the trick. But please mind that a moving background can waste such resources as CPU load and battery.
UPDATE (moving: as any other view)
To make a view move, you can either use an animation or change the view position programmatically. I did the latter in response to a touch, you probably will choose the former. There is a lot about animations on SO.
I would try to take the background image 2 times wider than the screen, set the left coordinate to a negative value, and animate changing this value to 0 (the image would move right, at least so it was in iOS).
Note 1.
To position a view inside an either LinearLayout or RelativeLayout you can use auxiliary transparent views.
For example, the layout below splits the screen in 5 areas:
11111111111
222 333
44444444444
and places an image in the corner to the right of "2" and above "4":
<RelativeLayout
android:id="#+id/sight"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<View
android:id="#+id/sightq1"
android:layout_width="fill_parent"
android:layout_height="80px"
android:layout_alignParentTop="true"
/>
<View
android:id="#+id/sightq4"
android:layout_width="fill_parent"
android:layout_height="80px"
android:layout_alignParentBottom="true"
/>
<View
android:id="#+id/sightq2"
android:layout_width="80px"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_above="#id/sightq4"
android:layout_below="#id/sightq1"
/>
<View
android:id="#+id/sightq3"
android:layout_width="80px"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_above="#id/sightq4"
android:layout_below="#id/sightq1"
/>
<!-- example: -->
<ImageView
android:id="#+id/..."
android:layout_toRightOf="#id/sightq2"
android:layout_alignTop="#id/sightq4"
android:src="#drawable/..."
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
Having said that, I have to note that probably you will not need auxiliary views, just positioning will do.
Note 2.
To get the actual view width/height of a view, you must use a ViewTreeObserver.OnGlobalLayoutListener and call v.getMeasuredWidth() and v.getMeasuredHeight() from onGlobalLayout(). These width and height are known only after layout happens.
v.getViewTreeObserver().addOnGlobalLayoutListener(mLayoutListener); to register a listener.

Android Studio: Graphics are cut

I have the Views attached to each other in the following order:
Activity->RelativeLayout->RelativeLayout->Text
When I change the Y of one of the Text attached to the inner RelativeLayout, parts of it are cut.
Here's a screenshot:
http://s28.postimg.org/ypmvrjz25/image.png
I'm coding purely in Java, no XML.
What's going on?
It looks like one layout is overlapping on another because the menu bar is pushing it down. If you just want the text centered I would suggest setting that in the parameters like so.
android:gravity="center"
This places the text in the center if that is what you want.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/textView12"
android:layout_gravity="center"
android:gravity="center_vertical|center_horizontal" />
</LinearLayout>
As #Jonathan Whalen suggested you probably have some overlap, I suggest you to change your relative layouts background color to see wich one is overlapping the text. Also try to not use fixed height for the layouts but use wrap_content instead, as fixed dims are frequently the cause of layouts overlap.

How can I put tabs NOT at the top of the layout?

I've read about using ActionBar Tabs, but I want to structure my layout so that I have the tabs somewhere not at the top (after a View) and the layout form the tab downwards to the end of the screen would be the area that changes fragments.
I've looked at a couple of SO questions that are sort of similar, and most mention ViewPager I think, but I haven't found any concrete answers as how to implement this. So how do I get my layout to have a common View, and then right underneath, the tab part? Can this be done with TabHost?
To better illustrate... this is my current XML for the layout (I deleted some attributes to keep it short):
<!-- top most layout -->
<ScrollView 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:context="com.xxxx.req.FinancialsActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- Layout that's always visible -->
<LinearLayout
android:id="#+id/"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<!-- This is where I want to have two tabs next to each other -->
<!-- Right underneath the tabs, I want a FrameLayout so I can
switch between two fragments -->
</LinearLayout>
</ScrollView>
So how do I get my layout to have a common View, and then right underneath, the tab part?
Put "the tab part" right where your code comments say that you want "the tab part". While that cannot be accomplished via action bar tabs, such tabs are deprecated anyway starting with the "L" Developer Preview. A ViewPager and tabbed indicator (e.g., PagerTabStrip) or a FragmentTabHost can go where your comments indicate.
Note that TabHost would not be practical, given that you want the tabs to be fragments -- you are better served using FragmentTabHost.

ANDROID: Adapter position returns to zero and re-adds views to ListView

My app requires the ability to add several views on one line in a user selected order.
I found this tutorial which seems to accomplish what I want with a bit of modification.
http://www.androidpeople.com/android-custom-listview-tutorial-example/
Having followed the tutorial and made the required changes, the code works except for one strange issue. The position increments but when it hits ~9 it returns to zero and then re-adds views that are already in the list and thus never reaches the >9 ones.
Also, if I scroll down to the bottom and then back up the very first entry has changed! It may change more but I haven't checked that.
Through some tests I have discovered that the textSize has some effect. If I set it small enough so that all 'rows' will show on screen at once then they appear fine.
This is my listview layout that gets inflated into the main layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="60dip"
style="#style/DefaultTheme">
<TextView
android:id="#+id/Line01"
android:layout_width="5dip"
android:layout_height="fill_parent"
android:background="#F00" />
<TextView
android:id="#+id/Line02"
android:layout_width="5dip"
android:layout_height="fill_parent"
android:background="#0F0" />
<TextView
android:id="#+id/Line03"
android:layout_width="5dip"
android:layout_height="fill_parent"
android:background="#00F"
android:layout_marginRight="5dip"/>
<LinearLayout
android:id="#+id/LinearLayout"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="2dip">
<TextView android:id="#+id/Name"
android:text="Name"
style="#style/Name" />
<TextView
android:id="#+id/Status"
android:text="Status"
style="#style/Status" />
</LinearLayout>
<ImageView
android:id="#+id/StatusImage"
style="#style/StatusImage" />
</LinearLayout>
I change background colours and text but that is all. Any ideas what is the problem?
Thanks!
That's because ListView recycles Views. It creates as many Views as required then the one which isn't available will be recycled as next.
So you have to set the colors/attributes in the getView or bindView methods of the adapter.
And btw. what you posted doesn't inflate the ListView, as there is no `' object in it. At best it could be a single ListView item, but not the listview itself ^^
I feel dumb for asking this now and not going back over the tutorial completely.
I was setting the values in my layout I place in the ListView on my main layout only when a new ViewHolder was created. Thus when I scrolled, the views were recycled, but never updated with the correct View settings.
All working fine now!
Cheers

How can I get a ListView and TextView to scroll as one unit when content is taller than the screen height?

I have a main menu screen with a simple ListView that contains "links" to further screens in my app (Browse, Bookmarks, Settings, About, etc.). Underneath the ListView there is a TextView (more accurately, a TextSwitcher that rotates TextViews) that changes every 10 seconds to display a new "tip".
In portrait mode, this works fine. There are my five list items in the ListView , and my tip label underneath. However, when I switch to landscape mode, the ListView is taller than the screen. The ListView scrolls normally, but I cannot scroll past the end of the ListView to see the TextView underneath.
I have tried every possible combination of Layouts, wrappers, ScrollViews, and layout_height parameters and I simply cannot get it to behave.
Here is the simplest code I can use to get the result pictured above:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:orientation="vertical"
android:layout_height="fill_parent">
<LinearLayout android:id="#+id/ListLayout"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<ListView android:id="#id/android:list" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_weight="1">
</ListView>
</LinearLayout>
<LinearLayout android:id="#+id/TipLayout"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_below="#+id/ListLayout">
<TextSwitcher android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/TipSwitcher">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textSize="7pt"
android:id="#+id/Tip1TextView" android:text="Tip: Hello, Android!"></TextView>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tip: This is the second TextView in the TipSwitcher!"
android:id="#+id/Tip2TextView" android:textSize="7pt"></TextView>
</TextSwitcher>
</LinearLayout>
</RelativeLayout>
Like I've said, I've already tried so many different combinations that I can't list them, and for the most part I was randomly inserting XML in an attempt to get something to work the way I wanted. So I'd greatly appreciate suggestions as to how I would go about doing this the right way.
Thanks.
EDIT: Something I forgot to mention, this may or may not be relevant. My MainMenuActivity is extending ListActivity. According to the docs, "ListActivity has a default layout that consists of a single, full-screen list in the center of the screen." But, "If you desire, you can customize the screen layout by setting your own view layout with setContentView() in onCreate()." So I don't think the ListActivity is interfering.
Put the TextSwitcher in the ListView itself. You can use addFooterView() for this.

Categories