Draw custom tab bar for Android app - java

I need to develop an app with tab bar on the bottom, but I have lots of problems with Fragments, where Android documentation shows how to use TabHost and Fragments.
Because there is nothing shown, about how to do it right with every tab stack.
As I can go to tab1 it's open Fragment A, then I want go into deep and open Fragment B and have the possibility to switch tab to tab2, as well as switch back seeing the same Fragment B in tab1.
There are some solutions creating for every tab a FragmentActivity, but for that management you should use TabActivity, which is deprecated.
So maybe I could draw my tab bar and put it on all layouts and every time user press tab bar button I just start an Activity ?
If this is possible maybe some had implemented this, or could show some tutorial how to draw, or use this?
Thanks.

In XML down_tabs.xml you add this code
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="fill_parent" android:layout_height="0dip"
android:layout_weight="1" />
<TabWidget android:id="#android:id/tabs"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_weight="0" />
</LinearLayout>
And in Activity class add tabs specifications as,
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.down_tabs);
initTabs();
}
private void initTabs() {
// Set Calendar Tab
// getTabWidget().setDividerDrawable(R.drawable.tab_divider);
getTabWidget().setPadding(0, 0, 0, 0);
addTab("", R.drawable.home_tab_drawable, CalendarUIActivity.class);
addTab("", R.drawable.lucky_dates_drawable, LuckyDatesActivity.class);
addTab("", R.drawable.life_stages_drawable, LifeStagesActivity.class);
addTab("", R.drawable.find_items_drawable, FindItemsActivity.class);
addTab("", R.drawable.more_tab_drawable, MoreActivity.class);
}
private void addTab(String labelId, int drawableId, Class<?> targetClass) {
TabHost tabHost = getTabHost();
Intent intent = new Intent(this, targetClass);
TabHost.TabSpec spec = tabHost.newTabSpec("tab" + labelId);
View tabIndicator = LayoutInflater.from(this).inflate(
R.layout.tab_indicator, getTabWidget(), false);
TextView title = (TextView) tabIndicator.findViewById(R.id.title);
title.setText(labelId);
ImageView icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageResource(drawableId);
tabIndicator.setBackgroundResource(R.drawable.tab_backgroud);
// //////////
spec.setIndicator(tabIndicator);
spec.setContent(intent);
tabHost.addTab(spec);
}
I hope it will works fine.

Yup good answer..fragments are easy to work..u know..
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<FrameLayout android:id="#android:id/tabcontent"
android:layout_width="fill_parent" android:layout_height="0dip"
android:layout_weight="1" />
<TabWidget android:id="#android:id/tabs"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_weight="0" />
</LinearLayout>
</TabHost>
for complete tutorial visit
http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/
http://android.codeandmagic.org/2011/07/android-tabs-with-fragments/

Related

How to fill page with overlay

I have a TRANSPARENT overlay in my android app that when user click on it,it fade but it can't fill all activity like below image
MainActivity :
<RelativeLayout
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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="This is Original View" />
</RelativeLayout>
OverlayActivity :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/over_lay_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="This is Overlay View" />
</RelativeLayout>
Java :
public class MainActivity extends Activity {
private ImageView mOverLayImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Dialog overlayInfo = new Dialog(MainActivity.this);
overlayInfo.requestWindowFeature(Window.FEATURE_NO_TITLE);
overlayInfo.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
overlayInfo.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
overlayInfo.setContentView(R.layout.overlay_view);
overlayInfo.show();
mOverLayImage = (ImageView) overlayInfo.findViewById(R.id.over_lay_image);
mOverLayImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
overlayInfo.cancel();
}
});
}
}
Use FrameLayout. Each item added to FrameLayout is on top of the previous one, like in this example the second TextView is on top of the frist one, but since it is not fully opaque, you can see them both!
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="Blablabla"
android:background="#FFFFFFFF"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000"
android:textColor="#FFFFFF"
android:text="I am on top"
android:gravity="center"
/>
</FrameLayout>
Now all you need to do is show/hide the overlayed items and you are good to go.
Delete your overlay activity, and inside your main activity apply this code :
<RelativeLayout
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=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="This is Original View" />
<!-- This is your overlay -->
<RelativeLayout android:id="#+id/over_lay_page"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/over_lay_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000"
android:onClick="clickedOverlay" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="This is Overlay View" />
</RelativeLayout>
</RelativeLayout>
Note that I added a line on your ImageView which runs a function when clicked, now on your java file add this function:
//The onClick on xml requires a function of signature void(View) which is the clicked view (in this case the ImageView)
public void clickedOverlay(View view)
{
//ImageView is clicked
RelativeLayout rlLayout = (RelativeLayout) findViewById(R.id.over_lay_page);
rlLayout.setVisibility(View.GONE);
}
This will make the RelativeLayout that contains the overlay views (including the ImageView which is clicked) to not only be invisible but not to interfere with anything. It also ignores input to it.
In case I misunderstood anything about your question feel free to correct me (I'm not sure I understood that completely).
Also if you want it to fade in or out or something like that you can do it with an AlphaAnimation.

Fragment switching when clicked on a texview Android

I am trying to change the display on my android screen when you click on a textview. This textview is inside a tab which is inside a tabhost. I created a fragment which would overlay on top of this tab when you click on it but having issues doing.
In my main activity I got this code;
tabHost.getTabContentView().findViewById(R.id.currentMoney).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.currentMoney:
android.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.tab2, new OverviewFragment());
transaction.commit();
}
}
});
This is the code that I have in my overview java class
public class OverviewFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.home_tab_transactionhistory, container, false);
}
}
What happens is when I run this home_tab_transactionhistory xml file comes up right underneath what ever I had before. Doesn't even show fully what ever I have got in the home_tab_transactionhistory xml file.
Below I have listed the xml code of the page that should take you to another page when you click on a text view;
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#369742"
android:gravity="start|end"
android:longClickable="true">
<TabHost
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tabHost"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:clickable="false">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="270dp"
android:layout_height="wrap_content"
android:background="#5DAD68"
android:clickable="false"
android:measureWithLargestChild="true"
android:orientation="horizontal"
android:layout_weight="1.04"
android:longClickable="false"
android:paddingTop="10dp"
android:paddingLeft="30dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"></TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="false">
<LinearLayout
android:id="#+id/tab2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:clickable="false"
android:background="#FFFFFF"
android:weightSum="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/currentMoney"
android:fontFamily="sans-serif-light"
android:onClick="showCurrentAccountMoney"
android:id="#+id/currentMoney"
android:paddingTop="5dp"
android:layout_gravity="center_horizontal"
android:textColor="#ff000000"
android:textSize="40dp" />
id of the textview is currentMoney
Please can someone help me fix this issue.
You should post the xml layout file where there is your clickable text view. To make the new Fragment overlay, you should add it to a FrameLayout which places its childs on top of each other.

Android: GridView Pull-To-Refresh - Override the animation?

So I implemented a Pull-to-Refresh on my GridView using android.support.v4.widget.SwipeRefreshLayout and it works well. But when dragging down the finger, only the animation plays and the 'GridView-being-pulled-down-animation' doesn't happen like it should when refreshing. The GridView stays intact while it gets updated. How can I override this animation method and add a GridView movement which clearly shows the animation where the GridView gets pulled down with the finger's movement? (similar to facebook, instagram's refresh)
And also maybe display a message at the top saying 'Refreshing'
My Code so far.
XML:
<RelativeLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ECECEC"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="#dimen/feed_item_margin"
android:layout_marginRight="#dimen/feed_item_margin"
android:layout_marginTop="#dimen/feed_item_margin"
android:orientation="vertical"
android:paddingBottom="#dimen/feed_item_padding_top_bottom"
android:paddingTop="#dimen/feed_item_padding_top_bottom" >
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<GridView
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentBottom="true"
android:columnWidth="100dp"
android:gravity="center"
android:numColumns="1"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
</RelativeLayout>
Code:
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
//my update process
RequestParams params = new RequestParams();
params.put("req", "dataReqAndroid");
invokeWS(params);
}
});
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);

How can I implement a ListView within a LinearLayout?

I am trying to make a simple Checkbook app, whose MainActivity stores a list of transactions. I would like a TextView at the top and bottom of the screen that show the account balance and an option to add a new transaction, respectively. I would like a list of transactions in between that scroll. I was able to implement a ListView and add a header and footer view, but if the transaction list exceeds the size of the screen the headers and footers can scroll off screen.
Is there any way to position a ListView within the linear layout, or freeze the headers/footers to stay on the screen?
Here is my XML file so far:
<TextView
android:id="#+id/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/add_transaction_string">
</TextView>
And here is my onCreate, which has no syntax errors but I am unable to click the footerview to add a transaction:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checkbook);
ListView list = (ListView) findViewById(R.id.transaction_list_view);
// Create a new Adapter
mAdapter = new TransactionAdapter(list.getContext());
// Inflate footerView and headerView
LayoutInflater inflater = getLayoutInflater();
TextView headerView = (TextView) inflater.inflate(R.layout.header_view, null);
TextView footerView = (TextView) inflater.inflate(R.layout.footer_view, null);
// Set listener for footerView
footerView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Intent transactionIntent = new Intent(CheckbookActivity.this, AddTransactionActivity.class);
startActivityForResult(transactionIntent, ADD_TRANSACTION_REQUEST);
}
});
list.setAdapter(mAdapter);
}
use the below code. This will satisfy your requirement. I tried this and working for me.
Relative layout with below,above attributes. Relativelayout is better than Linear layout with weight method.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/relative"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:gravity="center_horizontal"
android:text="ListView Heading" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:gravity="center_horizontal"
android:text="ListView Footer" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/textView1"
android:layout_above="#id/textView2"
></ListView>
The UI will like this
Try this way, hope this will help you to solve your problem.
Instead of using header/footer just put as below code in your XML:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="#+id/header_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/add_transaction_string">
</TextView>
</LinearLayout>
Yes, you can do it with weightsum and layout_weight in linearlayout and also you can create this type of view using RelativeLayout.
1) In LinearLayout just add weightsum="1" to your linearlayout and add layout_weight="0.2" to each of your header and footer and add layout_weight="0.6" to your listview.
2) In relativeLayout add alignParentTop to your header and alignParentBottom to your footer and set listview to layout_below="#+id/header" and layout_above="2+id/footer"
I found a possible solution for your problem from a similiar post. Hope this helps you.
For what you are trying to accomplish to freeze the header/footer. It will be easier to use a relative layout to position the header/footer then have your listview in the middle
<RelativeLayout ...>
<TextView
android:id="#+id/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header_view"
android:layout_above="#+id/footer_view">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text="#string/add_transaction_string">
</TextView>
</RelativeLayout>
You can use a LinearLayout for this task. But I don't recommend it as it's a bit "hacky".
Get all the elements in a array: Example:- (weatherArray)
Loop through all the elements :-
Example:-
mainLayout = ((LinearLayout)refreshObj.get("mainLayout"));
mainLayout.removeAllViews();
for (int i = 0; i < weatherArray.length(); i++) {
View childView = getLayoutInflater().inflate(R.layout.weather_row4_item, mainLayout,false);
TextView todayTempStatus = (TextView) childView.findViewById(R.id.todayTempStatus);
todayTempStatus.setText("");
}
This is an example without using listview, which we will populate lienarlayout using child view.

add tab host with activities inside fragment

Good day. I have some problem.
I have app with listview at left and detail view at right. In right view I have a fragment with tab host. But I also want to add activities for all tabs.
For example:
I have clients list at left.
At right I have tabs: "clients comments", "clients photos", "clients Info"
In clients comments I need in activity with comments for this client, and with possibility to add new comment.
I have already made a list view and detail, but I have problems with integration tab hosts into it. So what I have. Here My code of detail fragment
public class ItemDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
DummyContent.DummyItem mItem;
private Activity lo_parentAct;
public ItemDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
if (mItem != null) {
Intent lv_intent;
// ((TextView) rootView.findViewById(R.id.item_detail)).setText(mItem.content);
TabHost tabHost=(TabHost)rootView.findViewById(R.id.tabHost);
tabHost.setup();
TabSpec spec1=tabHost.newTabSpec("Tab 1");
spec1.setIndicator("Общая информация");
lo_parentAct = this.getActivity();
lv_intent = new Intent(lo_parentAct, ClientInfoActivity.class);
TabSpec spec2=tabHost.newTabSpec("Tab 2");
spec2.setIndicator("Заметки");
lv_intent = new Intent(lo_parentAct, ClientCommentsActivity.class);
TabSpec spec3=tabHost.newTabSpec("Tab 3");
spec3.setIndicator("Фото");
lv_intent = new Intent(lo_parentAct, ClientPhotosActivity.class);
tabHost.addTab(spec1);
tabHost.addTab(spec2);
tabHost.addTab(spec3);
}
return rootView;
}
}
An the layout
<TabHost android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tabHost"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<TabWidget
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#android:id/tabs"
/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#android:id/tabcontent"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/tab1"
android:orientation="vertical"
android:paddingTop="60px"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab1"
android:id="#+id/txt1"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tab2"
android:orientation="vertical"
android:paddingTop="60px"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 2"
android:id="#+id/txt2"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tab3"
android:orientation="vertical"
android:paddingTop="60px"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="100px"
android:text="This is tab 3"
android:id="#+id/txt3"
/>
</LinearLayout>
</FrameLayout>
</TabHost>
add tab host with activities inside fragment
You can't put activities into fragments!
As I understand - you want to put TabActivity (wich is deprecated) with different activities into your main activity's root Fragment - this way is absolutely wrong.
One way to implement what you need is:
create one FragmentActivity.
put TabWidget into root layout of your FragmentActivity.
then put different Fragments into you TabWidget's tabs.
You can look at my similar answer with code examples into another theme (link).

Categories