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>
<?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>
<?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>
<?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>
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; } }
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); } }
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; }
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="Theme" parent="android:Theme"> <item name="android:windowNoTitle">true</item> </style> </resources>工程图: