实现了一个自定义tabBar,效果如下:
代码写的有点罗嗦:控件如下:
import java.util.Vector;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.PopupWindow;
import com.example.zoeicetabgroup.R;
/**
* custom tab bar
* @author zoeice
*
*/
public class LPTabGroupWithGesture extends View implements OnGestureListener, OnTouchListener{
private int tabNum = 0;
private int curSelect = 0;
private int curX = 0;
private int savedClickIndex = -1;
private int savedX = 0;
private boolean isDraging = false;
private int dragCurrentX = 0;
private int dragSavedX = 0;
private int dragSelectIndex = -1;
private final int TEXT_SIZE = 30;
private final int TAB_MARGIN = 30;
private int tabWidth = 200;
private int tabHeight = 0;
private int tabGap = 30;// IF
private int tabAddWidth = 90;// IF
private Bitmap bitCur;
private NinePatch npCur;
private Bitmap bitNor;
private NinePatch npNor;
private Bitmap bitAdd;
private int screenWidth;
private int screenHeight;
private float screenDensity;
private PopupWindow popMenu;
private OnTabItemClickListener clickListener;
private GestureDetector mGestureDetector;
private Vector<TabItem> tabLists = new Vector<TabItem>();
public LPTabGroupWithGesture(Context context, Vector<TabItem> vec) {
this(context);
tabLists = vec;
tabNum = vec.size();
}
public LPTabGroupWithGesture(Context context) {
super(context);
if(tabNum == 0){
tabNum = 1;
tabLists.add(new TabItem());
}
initParams(context);
}
/**
* init view's params
*/
private void initParams(Context context){
this.setLongClickable(true);
this.setOnTouchListener(this);
mGestureDetector = new GestureDetector(context, this);
mGestureDetector.setIsLongpressEnabled(true);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
screenWidth = displayMetrics.widthPixels;
screenHeight = displayMetrics.heightPixels;
screenDensity = displayMetrics.density;
bitCur = BitmapFactory.decodeResource(getResources(),
R.drawable.tab);
npCur = new NinePatch(bitCur, bitCur.getNinePatchChunk(), null);
tabHeight = bitCur.getHeight();
bitNor = BitmapFactory.decodeResource(getResources(),
R.drawable.tab);
npNor = new NinePatch(bitNor, bitNor.getNinePatchChunk(), null);
bitAdd = BitmapFactory.decodeResource(getResources(),
R.drawable.tab_add);
tabAddWidth = bitAdd.getWidth();
}
/**设置当前选中选项的位置*/
public void setCurrentSelect(int index) {
curSelect = index;
invalidate();
}
/**
* @see android.view.View#measure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(screenWidth, tabHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(0xff707070);
paint.setTextSize(TEXT_SIZE);
/*draw bg*/
canvas.drawARGB(0xff, 0xa1, 0x9c, 0xff);
if(isDraging){
int dX = dragCurrentX + (tabWidth - tabGap) * curSelect;
/*draw normal tab*/
for (int i = tabNum - 1; i >= 0; i--) {
if (i != curSelect) {
int nX = curX + (tabWidth - tabGap) * i ;
if(i > savedClickIndex && savedClickIndex > -1){
nX -= tabWidth - tabGap;
}
if(i > dragSelectIndex && dragSelectIndex > -1){
nX += tabWidth - tabGap;
}
Rect nR = new Rect(nX, 0, nX + tabWidth, tabHeight);
npNor.draw(canvas, nR);
//draw text
canvas.save();
canvas.clipRect(new Rect(nX + TAB_MARGIN, 0, nX + tabWidth - TAB_MARGIN, tabHeight));
canvas.drawText(tabLists.get(i).name, nX + TAB_MARGIN, (tabHeight + TEXT_SIZE) >> 1, paint);
canvas.restore();
}
}
/*draw shape for above normal tab*/
canvas.drawARGB(0x50, 0x00, 0x00, 0x00);
/*draw buttom line*/
Paint paintShape = new Paint();
paintShape.setColor(0x50000000);
canvas.drawRect(0, tabHeight - 2, screenWidth, tabHeight, paintShape);
/*draw current selected tab*/
Rect dR = new Rect(dX, 0, dX + tabWidth, tabHeight);
npCur.draw(canvas, dR);
//draw current text
paint.setColor(0xff456789);
canvas.drawText(tabLists.get(curSelect).name, dX + tabGap, (tabHeight + TEXT_SIZE) >> 1, paint);
/*draw add button*/
int aX = curX + (tabWidth - tabGap) * tabNum;
if(dX + tabWidth > aX)
canvas.drawBitmap(bitAdd, dX + tabWidth - tabGap, 0, paint);
else
canvas.drawBitmap(bitAdd, aX, 0, paint);
}else{
/*draw normal tab*/
for (int i = tabNum - 1; i >= 0; i--) {
if (i != curSelect) {
int nX = curX + (tabWidth - tabGap) * i ;
Rect nR = new Rect(nX, 0, nX + tabWidth, tabHeight);
npNor.draw(canvas, nR);
//draw text
canvas.save();
canvas.clipRect(new Rect(nX + TAB_MARGIN, 0, nX + tabWidth - TAB_MARGIN, tabHeight));
canvas.drawText(tabLists.get(i).name, nX + TAB_MARGIN, (tabHeight + TEXT_SIZE) >> 1, paint);
canvas.restore();
}
}
/*draw shape for above normal tab*/
canvas.drawARGB(0x50, 0x00, 0x00, 0x00);
/*draw buttom line*/
Paint paintShape = new Paint();
paintShape.setColor(0x50000000);
canvas.drawRect(0, tabHeight - 2, screenWidth, tabHeight, paintShape);
/*draw current selected tab*/
int cX = curX + (tabWidth - tabGap) * curSelect;
Rect cR = new Rect(cX, 0, cX + tabWidth, tabHeight);
npCur.draw(canvas, cR);
//draw current text
paint.setColor(0xff456789);
canvas.drawText(tabLists.get(curSelect).name, cX + tabGap, (tabHeight + TEXT_SIZE) >> 1, paint);
/*draw add button*/
canvas.drawBitmap(bitAdd, curX + (tabWidth - tabGap) * tabNum, 0, paint);
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mGestureDetector.onTouchEvent(event)) {
return true;
}
if(event.getAction() == MotionEvent.ACTION_UP) {
if(isDraging ) {
if(dragSelectIndex != curSelect){
if(dragSelectIndex >= tabNum){
dragSelectIndex = tabNum - 1;
}
TabItem tempItem = tabLists.elementAt(curSelect);
tabLists.removeElementAt(curSelect);
tabLists.add(dragSelectIndex, tempItem);
}
float x = event.getX();
curSelect = (int) ((x - curX) / (tabWidth - tabGap));
if(curSelect >= tabNum){
curSelect = tabNum - 1;
}
isDraging = false;
dragSelectIndex = -1;
dragCurrentX = 0;
dragSavedX = 0;
invalidate();
}
}
return false;
}
/**选项点击事件设置*/
public void setOnTabItemClickListener(OnTabItemClickListener click) {
this.clickListener = click;
}
/**选项点击事件接口*/
public interface OnTabItemClickListener {
public void onclickListenr(int index);
}
@Override
public boolean onDown(MotionEvent event) {
float x = event.getX();
savedClickIndex = (int) ((x - curX) / (tabWidth - tabGap));
if(savedClickIndex == curSelect){
isDraging = true;
dragSavedX = savedX;
clickListener.onclickListenr(savedClickIndex);
}
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if(isDraging ) {
if(dragSelectIndex != curSelect){
if(dragSelectIndex >= tabNum){
dragSelectIndex = tabNum - 1;
}
TabItem tempItem = tabLists.elementAt(curSelect);
tabLists.removeElementAt(curSelect);
tabLists.add(dragSelectIndex, tempItem);
}
float x = e2.getX();
curSelect = (int) ((x - curX) / (tabWidth - tabGap));
if(curSelect >= tabNum){
curSelect = tabNum - 1;
}
isDraging = false;
dragSelectIndex = -1;
dragCurrentX = 0;
dragSavedX = 0;
invalidate();
}
return true;
}
@Override
public void onLongPress(MotionEvent event) {
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
int tempWidth = (tabWidth - tabGap) * tabNum + tabAddWidth;
if(isDraging){
//drag
int nextX = (int) (dragSavedX + e2.getX() - e1.getX());
dragSelectIndex = (int) ((e2.getX() - curX) / (tabWidth - tabGap));
dragCurrentX = nextX;
invalidate();
}else{
//move
int nextX = (int) (savedX - distanceX);
if(tempWidth > screenWidth && (nextX <=0 && nextX + tempWidth >= screenWidth)){
curX = nextX;
savedX = curX;
invalidate();
}
}
return false;
}
@Override
public void onShowPress(MotionEvent event) {
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
float x = event.getX();
int curClickIndex = (int) ((x - curX) / (tabWidth - tabGap));
if(savedClickIndex == curClickIndex){
if(curClickIndex < tabNum){
setCurrentSelect(curClickIndex);
clickListener.onclickListenr(curClickIndex);
}else if(curClickIndex == tabNum){
tabLists.add(new TabItem());
tabNum++;
curX = screenWidth - tabAddWidth - (tabWidth - tabGap) * tabNum;
setCurrentSelect(tabNum - 1);
clickListener.onclickListenr(curClickIndex);
invalidate();
}
}
savedClickIndex = -1;
savedX = curX;
return false;
}
}
tabItem类:
public class TabItem{
public int index;
public String name = "New Tab";
public String url = "www.baidu.com";
}
调用如下:
Vector<TabItem> vec = new Vector<TabItem>();
for(int i = 0; i < 4; i++){
TabItem item = new TabItem();
item.name = "名字" + i;
vec.add(item);
}
LPTabGroupWithGesture tabGroup = new LPTabGroupWithGesture(this, vec);
LayoutParams lptab = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
addContentView(tabGroup, lptab);
final TextView txt = new TextView(this);
LayoutParams lptxt = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
txt.setPadding(0, 100, 0, 0);
addContentView(txt, lptxt);
tabGroup.setOnTabItemClickListener(new OnTabItemClickListener() {
@Override
public void onclickListenr(int index) {
// TODO Auto-generated method stub
txt.setText("你点击了选项" + (index + 1));
}
});