android有个tab的实现,不过是顶部tab,有时候项目需要底部tab实现,像iphone一样,怎么办呢?
网上找了点资料,项目里别的同事以前也实现过,我就拿过来学习了一下:
先贴一下运行之后的效果图:
这个是MainActivity,的布局页面main.xml底部是一个自己重写的一个ImageView,通过重绘四个bitmap和text,然后点击相应的tab显示不同的layout,总共有四个layout,也是自己重写的linearlayout。
这个是登录页面:
点击登陆就会登陆到主界面。
源代码包就不上传了额,因为公司加密的远古。
代码:
初始页面:
<?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="fill_parent"
>
<ViewFlipper
android:id="@+id/init_flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<include layout="@layout/login" />
<include layout="@layout/reg" />
</ViewFlipper>
</LinearLayout>
登陆layout:
<?xml version="1.0" encoding="utf-8"?>
<cn.edu.wtu.imile.LoginLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<include layout="@layout/app_title"/>
<TextView
android:text="@string/login_nickname"
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</TextView>
<EditText
android:layout_height="wrap_content"
android:id="@+id/login_nickname"
android:layout_width="match_parent"
android:singleLine="true"
>
</EditText>
<TextView
android:text="@string/login_password"
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</TextView>
<EditText
android:layout_height="wrap_content"
android:id="@+id/login_password"
android:layout_width="match_parent"
android:singleLine="true"
>
</EditText>
<Button
android:text="@string/login_login"
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/btn_register"
android:text="@string/login_register"
>
</Button>
</cn.edu.wtu.imile.LoginLayout>
注册layout:
<?xml version="1.0" encoding="utf-8"?>
<cn.edu.wtu.imile.RegisterLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<include layout="@layout/app_title"/>
<TextView
android:text="@string/login_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</TextView>
<EditText
android:layout_height="wrap_content"
android:id="@+id/reg_nickname"
android:layout_width="wrap_content"
android:singleLine="true"
>
</EditText>
<TextView
android:text="@string/login_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</TextView>
<EditText
android:layout_height="wrap_content"
android:id="@+id/reg_password"
android:layout_width="wrap_content"
android:singleLine="true"
>
</EditText>
<TextView
android:text="@string/login_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</TextView>
<EditText
android:layout_height="wrap_content"
android:id="@+id/reg_email"
android:layout_width="wrap_content"
android:singleLine="true"
>
</EditText>
<Button
android:id="@+id/btn_enter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login_register"
/>
</cn.edu.wtu.imile.RegisterLayout>
程序title:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
/>
</LinearLayout>
好友layout:
<?xml version="1.0" encoding="utf-8"?>
<cn.edu.wtu.imile.BuddyLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:text="好友列表"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</cn.edu.wtu.imile.BuddyLayout>
会话列表:
<?xml version="1.0" encoding="utf-8"?>
<cn.edu.wtu.imile.SessionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:text="会话列表"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</cn.edu.wtu.imile.SessionLayout>
找朋友页面:
<?xml version="1.0" encoding="utf-8"?>
<cn.edu.wtu.imile.SearchLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:text="找朋友列表"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</cn.edu.wtu.imile.SearchLayout>
聊天室页面:
<?xml version="1.0" encoding="utf-8"?>
<cn.edu.wtu.imile.ChatroomLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:text="聊天室列表"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</cn.edu.wtu.imile.ChatroomLayout>
初始activity:包含两个layout,一个登陆,一个注册:
package cn.edu.wtu.imile;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.ViewFlipper;
import cn.edu.wtu.imile.ui.ImileLayout;
import cn.edu.wtu.imile.utils.Constants;
import cn.wtu.edu.imile.R;
public class ImileActivity extends Activity {
/** Called when the activity is first created. */
private static final String TAG = "ImileActivity";
private static final int LOGIN = 0;
public static final int REGISTER = 1;
private ViewFlipper mFlipper;
// private ImileLayout mCurrentLayout;
public static int mCurrentId = LOGIN;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.init);
mFlipper = (ViewFlipper)findViewById(R.id.init_flipper);
// mCurrentLayout = (ImileLayout) mFlipper.getChildAt(mCurrentId);
for(int i =0; i< mFlipper.getChildCount(); i++){
ImileLayout layout = (ImileLayout) mFlipper.getChildAt(i);
layout.onCreate(this);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0){
Log.d(TAG, "**");
if(mCurrentId == LOGIN){
showDialog(Constants.DIALOG_EXIT);
}else if(mCurrentId == REGISTER){
mCurrentId = LOGIN;
mFlipper.setDisplayedChild(mCurrentId);
return false;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
protected Dialog onCreateDialog(int id) {
super.onCreateDialog(id);
switch(id){
case Constants.DIALOG_EXIT:
return new AlertDialog
.Builder(this)
.setTitle(R.string.login_exit_title)
.setMessage(getString(R.string.login_exit_msg))
.setPositiveButton(R.string.dialog_btn_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ImileActivity.this.finish();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
})
.setNegativeButton(R.string.dialog_btn_exit, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
}
})
.create();
}
return null;
}
}
登陆layout,注册layout:
package cn.edu.wtu.imile;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ViewFlipper;
import cn.edu.wtu.imile.ui.ImileLayout;
import cn.wtu.edu.imile.R;
public class LoginLayout extends ImileLayout implements OnClickListener{
private static final String TAG = "LoginLayout";
private Context mCtx;
private Button mBtnLogin;
private Button mBtnRegister;
public LoginLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onCreate(Context ctx) {
super.onCreate(ctx);
mCtx = ctx;
mBtnLogin = (Button)findViewById(R.id.btn_login);
mBtnRegister= (Button)findViewById(R.id.btn_register);
mBtnLogin.setOnClickListener(this);
mBtnRegister.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn_login:
Toast.makeText(mCtx, TAG, Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.setClass(mCtx, MainActivity.class);
mCtx.startActivity(intent);
break;
case R.id.btn_register:
ImileActivity.mCurrentId = 1;
((ViewFlipper)((ImileActivity)mCtx).findViewById(R.id.init_flipper)).setDisplayedChild(1);
break;
}
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public Dialog onCreateDialog(int id) {
return super.onCreateDialog(id);
}
}
package cn.edu.wtu.imile;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import cn.edu.wtu.imile.ui.ImileLayout;
import cn.wtu.edu.imile.R;
public class RegisterLayout extends ImileLayout implements OnClickListener{
private static final String TAG = "RegisterLayout";
private Button mBtnEnter;
private Context mCtx;
public RegisterLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onCreate(Context ctx) {
super.onCreate(ctx);
mCtx = ctx;
mBtnEnter = (Button)findViewById(R.id.btn_enter);
mBtnEnter.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Toast.makeText(mCtx, TAG, Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.setClass(mCtx, MainActivity.class);
mCtx.startActivity(intent);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public Dialog onCreateDialog(int id) {
return super.onCreateDialog(id);
}
}
主activity:
package cn.edu.wtu.imile;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ViewFlipper;
import cn.edu.wtu.imile.ui.ImileTabView;
import cn.edu.wtu.imile.ui.ImileTabView.OnTabClickListener;
import cn.edu.wtu.imile.ui.ImileTabView.TabMember;
import cn.wtu.edu.imile.R;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final int TAB_BUDDY = 0;
public static final int TAB_SESSION = 1;
public static final int TAB_SEARCH = 2;
public static final int TAB_CHATROOM = 3;
private ViewFlipper mFlipper;
private ImileTabView mTab;
private int mCurrentId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mFlipper = (ViewFlipper) findViewById(R.id.main_flipper);
mTab = (ImileTabView) findViewById(R.id.Tabs);
mTab.addTabMember(new TabMember(TAB_BUDDY, R.drawable.tab1_normal, R.drawable.tab1_over,getString(R.string.tab_buddy)));
mTab.addTabMember(new TabMember(TAB_SESSION, R.drawable.tab2_normal, R.drawable.tab2_over, getString(R.string.tab_session)));
mTab.addTabMember(new TabMember(TAB_SEARCH, R.drawable.tab3_normal, R.drawable.tab3_over, getString(R.string.tab_search)));
mTab.addTabMember(new TabMember(TAB_CHATROOM, R.drawable.tab4_normal, R.drawable.tab4_over, getString(R.string.tab_chatroom)));
mTab.setOnTabClickListener(new OnTabClickListener() {
@Override
public void onTabClick(int tabId) {
mCurrentId = tabId;
mFlipper.setDisplayedChild(tabId);
}
});
}
}
好友,会话,找朋友,聊天室页面:
package cn.edu.wtu.imile;
import android.app.Dialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import cn.edu.wtu.imile.ui.ImileLayout;
public class BuddyLayout extends ImileLayout {
public BuddyLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onCreate(Context ctx) {
super.onCreate(ctx);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public Dialog onCreateDialog(int id) {
return super.onCreateDialog(id);
}
}
package cn.edu.wtu.imile;
import android.app.Dialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import cn.edu.wtu.imile.ui.ImileLayout;
public class SessionLayout extends ImileLayout {
public SessionLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onCreate(Context ctx) {
super.onCreate(ctx);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public Dialog onCreateDialog(int id) {
return super.onCreateDialog(id);
}
}
package cn.edu.wtu.imile;
import android.app.Dialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import cn.edu.wtu.imile.ui.ImileLayout;
public class SearchLayout extends ImileLayout {
public SearchLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onCreate(Context ctx) {
super.onCreate(ctx);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public Dialog onCreateDialog(int id) {
return super.onCreateDialog(id);
}
}
package cn.edu.wtu.imile;
import android.app.Dialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import cn.edu.wtu.imile.ui.ImileLayout;
public class ChatroomLayout extends ImileLayout {
public ChatroomLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onCreate(Context ctx) {
super.onCreate(ctx);
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public Dialog onCreateDialog(int id) {
return super.onCreateDialog(id);
}
}
package cn.edu.wtu.imile.ui;
import android.app.Dialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;
public class ImileLayout extends LinearLayout{
public ImileLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void onCreate(Context ctx){
}
public void onStart(){
}
public void onResume(){
}
public void onPause(){
}
public void onStop(){
}
public void onDestroy(){
}
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
return true;
}
public Dialog onCreateDialog(int id) {
return null;
}
}
package cn.edu.wtu.imile.ui;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
public class ImileTabView extends ImageView {
private static final String TAG = "ImileTabView";
private Paint mBitmapPaint;
private Paint mTextPaint;
private ArrayList<TabMember> mTabMembers;
private int mActiveTabId;
private OnTabClickListener mListener;
private Context mCtx;
public ImileTabView(Context context, AttributeSet attrs) {
super(context, attrs);
mCtx = context;
mTabMembers = new ArrayList<TabMember>();
mBitmapPaint = new Paint();
mBitmapPaint.setAntiAlias(true);
mTextPaint = new Paint();
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setColor(0xffffffff);
mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
mTextPaint.setAntiAlias(true);
DisplayMetrics metrics = new DisplayMetrics();
((Activity)mCtx).getWindowManager().getDefaultDisplay().getMetrics(metrics);
float density = metrics.density;
float txtSize = 16;
if(density <= 0.75){
txtSize = 10;
}else if(density == 1.0){
txtSize = 14;
}else{
txtSize = 20;
}
mTextPaint.setTextSize(txtSize);
mActiveTabId = 0;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.d(TAG, "ImileTabView onDraw...");
Rect r = new Rect();
this.getDrawingRect(r);
int singleTabWidth = r.right/(mTabMembers.size()!= 0 ? mTabMembers.size() : 1);
Bitmap icon = null, iconSelected = null;
for(int i=0; i<mTabMembers.size(); i++){
TabMember tab = mTabMembers.get(i);
icon = BitmapFactory.decodeResource(getResources(), tab.getIconId());
iconSelected = BitmapFactory.decodeResource(getResources(), tab.getIconSelectedId());
if(mActiveTabId == i){
int tabX = singleTabWidth*i+(singleTabWidth/2 - iconSelected.getWidth()/2);
canvas.drawBitmap(iconSelected, tabX, r.top+5, null);
mTextPaint.setColor(0xffffffff);
canvas.drawText(tab.getText(), singleTabWidth*i+singleTabWidth/2, r.bottom-8, mTextPaint);
}else{
int tabX = singleTabWidth*i + (singleTabWidth/2 - icon.getWidth()/2);
canvas.drawBitmap(icon, tabX, r.top+5, null);
mTextPaint.setColor(0xffa5b5ce);
canvas.drawText(tab.getText(), singleTabWidth*i + singleTabWidth/2, r.bottom-8, mTextPaint);
}
icon.recycle();
iconSelected.recycle();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Rect r = new Rect();
this.getDrawingRect(r);
float singleTabWidth = r.right /(mTabMembers.size() != 0 ? mTabMembers.size() : 1);
int tabId = (int) (event.getX()/singleTabWidth - (event.getX()/singleTabWidth)%1);
mActiveTabId = tabId;
if(mListener != null){
mListener.onTabClick(mTabMembers.get(tabId).getId());
}
return super.onTouchEvent(event);
}
public void addTabMember(TabMember tab){
mTabMembers.add(tab);
}
public void setTabMember(int index, TabMember tab){
mTabMembers.add(index, tab);
}
public void setOnTabClickListener(OnTabClickListener onTabClickListener){
mListener = onTabClickListener;
}
public static class TabMember{
private int id;
private int iconId;
private int iconSelectedId;
private String text;
public TabMember(int id, int iconId, int iconSelectedId, String text){
this.id = id;
this.iconId = iconId;
this.iconSelectedId = iconSelectedId;
this.text = text;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getIconId() {
return iconId;
}
public void setIconId(int iconId) {
this.iconId = iconId;
}
public int getIconSelectedId() {
return iconSelectedId;
}
public void setIconSelectedId(int iconSelectedId) {
this.iconSelectedId = iconSelectedId;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
public interface OnTabClickListener{
public void onTabClick(int tabId);
}
}
package cn.edu.wtu.imile.utils;
public class Constants {
public static final int DIALOG_EXIT = 0x1001;
}
风格,去掉title,自定义title:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme" parent="android:Theme">
<item name="android:windowNoTitle">true</item>
</style>
</resources>
工程图:
所使用图片