android仿iphone主题效果的主菜单

android仿iphone主题效果的主菜单,第1张

概述现在很多第三方Launcher((如360Launcher,GoLauncher)带有iphone主题,相信玩Android的人大都知道。

现在很多第三方Launcher((如360Launcher,Golauncher)带有iphone主题,相信玩AndroID的人大都知道。

本例实现仿iphone主题的launcher的冰山一角。如下图:

      

效果看,大概就能猜出用什么控件类(支持左右滑动的控件类+GrIDVIEw),支持左右滑动的控件类,有很多了比如常用的gallery,VIEwPager,VIEwFlipper,VIEwFlow等等,本例自定义继承VIEwGroup的。看过launcher源码的人应该都知道 有个Workspace类继承VIEwGroup实现主菜单的。

闲话不多说了!

主布局:main.xml

<?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"  androID:orIEntation="vertical" >   <com.xyz.workspace.Workspace   androID:ID="@+ID/workspace"   androID:layout_wIDth="fill_parent"   androID:layout_height="fill_parent" />   <com.xyz.workspace.PageIndicator   androID:ID="@+ID/indicator"   androID:layout_wIDth="wrap_content"   androID:layout_height="wrap_content"   androID:layout_alignParentBottom="true"   androID:layout_centerHorizontal="true"   androID:layout_marginBottom="20dip" />  </relativeLayout> 

第一个自定义类Workspace就是实现左右滑动的,第二个类PageIndicator做指示器用。
Workspace.java

package com.xyz.workspace;  import java.util.List;  import androID.content.Context; import androID.util.AttributeSet; import androID.vIEw.MotionEvent; import androID.vIEw.VeLocityTracker; import androID.vIEw.VIEw; import androID.vIEw.VIEwConfiguration; import androID.vIEw.VIEwGroup; import androID.Widget.Scroller;  public class Workspace extends VIEwGroup {   private static final String TAG = "Workspace";  private Scroller mScroller;  private VeLocityTracker mVeLocityTracker;   private static final int DEFAulT_SCREEN = 0;  private static final int touch_STATE_REST = 0;  private static final int touch_STATE_SCRolliNG = 1;  private static final int SNAP_VELociTY = 600;  public static final int APP_PAGE_SIZE = 16;   private int mCurScreen;  private int mtouchState = touch_STATE_REST;  private int mtouchSlop;  private float mLastMotionX;  private float mLastMotionY;   private OnVIEwChangedListener mOnVIEwChangedListener;   public Workspace(Context context,AttributeSet attrs) {   this(context,attrs,0);   // Todo auto-generated constructor stub  }   public Workspace(Context context,AttributeSet attrs,int defStyle) {   super(context,defStyle);   // Todo auto-generated constructor stub   mScroller = new Scroller(context);   mCurScreen = DEFAulT_SCREEN;   mtouchSlop = VIEwConfiguration.get(getContext()).getScaledtouchSlop();  }   @OverrIDe  protected voID onLayout(boolean changed,int l,int t,int r,int b) {   // Todo auto-generated method stub   if (changed) {    int childleft = 0;    final int childCount = getChildCount();    for (int i = 0; i < childCount; i++) {     final VIEw childVIEw = getChildAt(i);     if (childVIEw.getVisibility() != VIEw.GONE) {      final int chilDWIDth = childVIEw.getMeasureDWIDth();      childVIEw.layout(childleft,childleft + chilDWIDth,childVIEw.getMeasuredHeight());      childleft += chilDWIDth;     }    }   }  }   @OverrIDe  protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) {   super.onMeasure(wIDthMeasureSpec,heightmeasureSpec);    final int wIDth = MeasureSpec.getSize(wIDthMeasureSpec);   final int wIDthMode = MeasureSpec.getMode(wIDthMeasureSpec);   if (wIDthMode != MeasureSpec.EXACTLY) {    throw new IllegalStateException(      "ScrollLayout only canmCurScreen run at EXACTLY mode!");   }    final int heightmode = MeasureSpec.getMode(heightmeasureSpec);   if (heightmode != MeasureSpec.EXACTLY) {    throw new IllegalStateException(      "ScrollLayout only can run at EXACTLY mode!");   }   final int count = getChildCount();   for (int i = 0; i < count; i++) {    getChildAt(i).measure(wIDthMeasureSpec,heightmeasureSpec);   }   scrollTo(mCurScreen * wIDth,0);  }   public voID snapToDestination() {   final int screenWIDth = getWIDth();   final int destScreen = (getScrollX() + screenWIDth / 2) / screenWIDth;   snapToScreen(destScreen);  }   public voID snapToScreen(int whichScreen) {   whichScreen = Math.max(0,Math.min(whichScreen,getChildCount() - 1));   if (getScrollX() != (whichScreen * getWIDth())) {    final int delta = whichScreen * getWIDth() - getScrollX();    mScroller.startScroll(getScrollX(),delta,Math.abs(delta) * 2);    mCurScreen = whichScreen;    invalIDate();   }   if (mOnVIEwChangedListener != null) {    mOnVIEwChangedListener.onChange(getChildCount(),whichScreen);   }  }   public voID setToScreen(int whichScreen) {   whichScreen = Math.max(0,getChildCount() - 1));   mCurScreen = whichScreen;   scrollTo(whichScreen * getWIDth(),0);  }   public int getCurScreen() {   return mCurScreen;  }   @OverrIDe  public voID computeScroll() {   // Todo auto-generated method stub   if (mScroller.computeScrollOffset()) {    scrollTo(mScroller.getCurrX(),mScroller.getCurrY());    postInvalIDate();   }  }   @OverrIDe  public boolean ontouchEvent(MotionEvent event) {   // Todo auto-generated method stub    if (mVeLocityTracker == null) {    mVeLocityTracker = VeLocityTracker.obtain();   }   mVeLocityTracker.addMovement(event);   final int action = event.getAction();   final float x = event.getX();   final float y = event.getY();   switch (action) {   case MotionEvent.ACTION_DOWN:    if (!mScroller.isFinished()) {     mScroller.abortAnimation();    }    mLastMotionX = x;    break;   case MotionEvent.ACTION_MOVE:    int deltaX = (int) (mLastMotionX - x);    mLastMotionX = x;    scrollBy(deltaX,0);    break;   case MotionEvent.ACTION_UP:    final VeLocityTracker veLocityTracker = mVeLocityTracker;    veLocityTracker.computeCurrentVeLocity(1000);    int veLocityX = (int) veLocityTracker.getXVeLocity();    if (veLocityX > SNAP_VELociTY && mCurScreen > 0) {     snapToScreen(mCurScreen - 1);    } else if (veLocityX < -SNAP_VELociTY      && mCurScreen < getChildCount() - 1) {     snapToScreen(mCurScreen + 1);    } else {     snapToDestination();    }    if (mVeLocityTracker != null) {     mVeLocityTracker.recycle();     mVeLocityTracker = null;    }    mtouchState = touch_STATE_REST;    break;   case MotionEvent.ACTION_CANCEL:    mtouchState = touch_STATE_REST;    break;   }   return true;  }   @OverrIDe  public boolean onIntercepttouchEvent(MotionEvent ev) {   // Todo auto-generated method stub   final int action = ev.getAction();   if ((action == MotionEvent.ACTION_MOVE)     && (mtouchState != touch_STATE_REST)) {    return true;   }   final float x = ev.getX();   final float y = ev.getY();   switch (action) {   case MotionEvent.ACTION_MOVE:    final int xDiff = (int) Math.abs(mLastMotionX - x);    if (xDiff > mtouchSlop) {     mtouchState = touch_STATE_SCRolliNG;    }    break;   case MotionEvent.ACTION_DOWN:    mLastMotionX = x;    mLastMotionY = y;    mtouchState = mScroller.isFinished() ? touch_STATE_REST      : touch_STATE_SCRolliNG;    break;   case MotionEvent.ACTION_CANCEL:   case MotionEvent.ACTION_UP:    mtouchState = touch_STATE_REST;    break;   }   return mtouchState != touch_STATE_REST;  }   public voID setonVIEwChangedListener(OnVIEwChangedListener l) {   mOnVIEwChangedListener = l;  }   public interface OnVIEwChangedListener {   public voID onChange(int cnt,int index);  } } 

PageIndicator.java:

package com.xyz.workspace;  import androID.content.Context; import androID.util.AttributeSet; import androID.vIEw.VIEw; import androID.Widget.ImageVIEw; import androID.Widget.linearLayout;  public class PageIndicator extends linearLayout {   private Context mContext;   public PageIndicator(Context ctx) {   super(ctx);   // Todo auto-generated constructor stub   mContext = ctx;  }   public PageIndicator(Context ctx,AttributeSet attrs) {   super(ctx,attrs);   // Todo auto-generated constructor stub   mContext = ctx;  }   public voID setIndication(int cnt,int index) {   if (index < 0 || index > cnt)    index = 0;   removeAllVIEws();   for (int i = 0; i < cnt; i++) {    ImageVIEw iv = new ImageVIEw(mContext);    iv.setimageResource(index == i ? R.drawable.indicator_current      : R.drawable.indicator);    if (i != 0 || i != cnt - 1) {     iv.setpadding(4,4,0);    }    addVIEw(iv);   }  } } 

这两个类的作用上面已经说了,有什么看不明白的欢迎提问,或自行Google。

 VIEwGroup实现好了,剩下就是实现GrIDVIEw显示系统所有app,主要工作也就是实现GrIDVIEw的适配器---GrIDAdapter

package com.xyz.workspace;  import java.util.List;  import androID.content.Componentname; import androID.content.Context; import androID.content.Intent; import androID.content.pm.ResolveInfo; import androID.vIEw.VIEw; import androID.vIEw.VIEw.OnClickListener; import androID.vIEw.VIEwGroup; import androID.Widget.BaseAdapter; import static com.xyz.workspace.Workspace.APP_PAGE_SIZE;  public class GrIDAdapter extends BaseAdapter implements OnClickListener {   private Context mContext;  private int mPageIndex;  private List<ResolveInfo> mPackagesInfo;   public GrIDAdapter(Context context,List<ResolveInfo> ListInfo,int page) {   mContext = context;   mPackagesInfo = ListInfo;   mPageIndex = page;  }   @OverrIDe  public int getCount() {   // Todo auto-generated method stub   int size = mPackagesInfo.size();   return size / APP_PAGE_SIZE > 0     && size - (APP_PAGE_SIZE * (mPageIndex + 1)) > 0 ? APP_PAGE_SIZE     : size % APP_PAGE_SIZE;  }   @OverrIDe  public Object getItem(int position) {   // Todo auto-generated method stub   return mPackagesInfo.get(APP_PAGE_SIZE * mPageIndex + position);  }   @OverrIDe  public long getItemID(int position) {   // Todo auto-generated method stub   return position;  }   @OverrIDe  public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup parent) {   // Todo auto-generated method stub   if (convertVIEw == null) {    convertVIEw = new AppItem(mContext,(ResolveInfo) getItem(position));   }   convertVIEw.setonClickListener(this);   convertVIEw.setTag(Integer.valueOf(position));   return convertVIEw;  }   /** 点击启动app **/  @OverrIDe  public voID onClick(VIEw v) {   // Todo auto-generated method stub   int pos = (Integer) v.getTag();   ResolveInfo info = (ResolveInfo) getItem(pos);   Intent i = new Intent(Intent.ACTION_MAIN);   i.addcategory(Intent.category_LAUNCHER);   i.setComponent(new Componentname(info.activityInfo.packagename,info.activityInfo.name));   mContext.startActivity(i);  } } 

GrIDVIEw的每个item不用说,一看就知道是一个linearLayout上面是个ImageVIEw,下面一个TextVIEw了。我把它封装了下---AppItem:

package com.xyz.workspace;  import androID.content.Context; import androID.content.pm.PackageManager; import androID.content.pm.ResolveInfo; import androID.graphics.Bitmap; import androID.graphics.Canvas; import androID.graphics.Paint; import androID.graphics.PixelFormat; import androID.graphics.PorterDuffXfermode; import androID.graphics.Rect; import androID.graphics.RectF; import androID.graphics.Bitmap.Config; import androID.graphics.PorterDuff.Mode; import androID.graphics.drawable.BitmapDrawable; import androID.graphics.drawable.Drawable; import androID.util.AttributeSet; import androID.vIEw.LayoutInflater; import androID.Widget.ImageVIEw; import androID.Widget.relativeLayout; import androID.Widget.TextVIEw;  public class AppItem extends relativeLayout {   private Context mContext;  private ImageVIEw mAppIcon;  private TextVIEw mAppname;  private ResolveInfo mAppInfo;  private PackageManager mPackageManager;   public AppItem(Context context) {   super(context);   mContext = context;   mPackageManager = context.getPackageManager();   LayoutInflater.from(context).inflate(R.layout.app_item,this);   mAppIcon = (ImageVIEw) findVIEwByID(R.ID.icon);   mAppname = (TextVIEw) findVIEwByID(R.ID.app_name);  }   public AppItem(Context context,ResolveInfo info) {   this(context);   mAppInfo = info;   show();  }   private voID show() {   String packagename = mAppInfo.activityInfo.packagename;   String appname = mAppInfo.activityInfo.loadLabel(mPackageManager)     .toString();   if (appname.equals("拨号")) {    mAppIcon.setimageResource(R.drawable.com_androID_phone);   } else if (packagename.equals("com.androID.contacts")) {    mAppIcon.setimageResource(R.drawable.com_androID_contacts);   } else if (packagename.equals("com.androID.mms")) {    mAppIcon.setimageResource(R.drawable.com_androID_mms);   } else if (packagename.equals("com.androID.music")) {    mAppIcon.setimageResource(R.drawable.com_androID_music);   } else if (packagename.equals("com.androID.browser")) {    mAppIcon.setimageResource(R.drawable.com_androID_browser);   } else if (packagename.equals("com.androID.settings")) {    mAppIcon.setimageResource(R.drawable.com_androID_settings);   } else if (packagename.equals("com.androID.email")) {    mAppIcon.setimageResource(R.drawable.com_androID_email);   } else if (packagename.equals("com.androID.calendar")) {    mAppIcon.setimageResource(R.drawable.com_androID_calendar);   } else if (packagename.equals("com.androID.calculator2")) {    mAppIcon.setimageResource(R.drawable.com_androID_calculator2);   } else if (packagename.equals("com.androID.deskclock")) {    mAppIcon.setimageResource(R.drawable.com_androID_deskclock);   } else if (packagename.equals("com.androID.camera")) {    mAppIcon.setimageResource(R.drawable.com_androID_camera);   } else if (packagename.equals("com.androID.soundrecorder")) {    mAppIcon.setimageResource(R.drawable.com_androID_soundrecorder);   } else if (packagename.equals("com.tencent.mobileqq")) {    mAppIcon.setimageResource(R.drawable.com_tencent_qq);   } else if (packagename.equals("com.tencent.mm")) {    mAppIcon.setimageResource(R.drawable.com_tencent_mm);   } else if (packagename.equals("com.tencent.mtt")) {    mAppIcon.setimageResource(R.drawable.com_tencent_mtt);   } else if (packagename.equals("com.sina.weibo")) {    mAppIcon.setimageResource(R.drawable.com_sina_weibo);   } else if (packagename.equals("com.sds.androID.ttpod")) {    mAppIcon.setimageResource(R.drawable.com_sds_androID_ttpod);    // ////////////////////////////////////////////////////////////////   } else if (packagename.equals("com.youdao.dict")) {    mAppIcon.setimageResource(R.drawable.com_youdao_dict);   } else {    mAppIcon.setimageDrawable(getRoundCornerDrawable(mContext,mAppInfo.activityInfo.loadIcon(mPackageManager),20));   }   mAppname.setText(appname);  }   private Drawable getRoundCornerDrawable(Context ctx,int resID,float roundPX /* <span >圆角半径 </span>*/) {   return getRoundCornerDrawable(ctx,mContext.getResources().getDrawable(resID),roundPX);  }   private Drawable getRoundCornerDrawable(Context ctx,Drawable drawable,float roundPX /* <span >圆角半径 </span>*/) {   int w = ctx.getResources()     .getDimensionPixelSize(R.dimen.app_icon_wIDth);   int h = w;    Bitmap bitmap = Bitmap     .createBitmap(       w,h,drawable.getopacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888         : Bitmap.Config.RGB_565);   Canvas canvas = new Canvas(bitmap);   drawable.setBounds(0,w,h);   drawable.draw(canvas);    int wIDth = bitmap.getWIDth();   int height = bitmap.getHeight();   Bitmap retBmp = Bitmap.createBitmap(wIDth,height,Config.ARGB_8888);   Canvas can = new Canvas(retBmp);    final int color = 0xff424242;   final Paint paint = new Paint();   final Rect rect = new Rect(0,wIDth,height);   final RectF rectF = new RectF(rect);    paint.setcolor(color);   paint.setAntiAlias(true);   can.drawARGB(0,0);   can.drawRoundRect(rectF,roundPX,paint);    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));   can.drawBitmap(bitmap,rect,paint);   return new BitmapDrawable(retBmp);  } } 

注意咯,show函数就是替换显示对应iphone里app的图标(来源反编译iphone主题的launcher或锁屏),利用 包名 判断是哪个应用再换上对应图标,例如com.androID.mms---信息,com.androID.contacts---联系人,这里有个疑问,为什么phone模块的package_name的也是com.androID.contacts,有人知道么?谢谢啦!
AppItem引用一个布局:
app_item.xml:

<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"  androID:layout_wIDth="@dimen/app_icon_wIDth"  androID:layout_height="@dimen/app_icon_height"  androID:gravity="center"  androID:orIEntation="vertical" >   <ImageVIEw   androID:ID="@+ID/icon"   androID:layout_wIDth="@dimen/app_icon_wIDth"   androID:layout_height="@dimen/app_icon_wIDth"   androID:layout_gravity="center_horizontal" />   <TextVIEw   androID:ID="@+ID/app_name"   androID:layout_wIDth="wrap_content"   androID:layout_height="wrap_content"   androID:layout_gravity="center_horizontal"   androID:ellipsize="marquee"   androID:maxWIDth="@dimen/app_icon_height"   androID:singleline="true"   androID:textcolor="@androID:color/white"   androID:textSize="12sp" />  </linearLayout> 

主Activity就是获取所有app信息及初始化界面,
MainActivty.java:

package com.xyz.workspace;  import java.util.List;  import com.xyz.workspace.Workspace.OnVIEwChangedListener;  import androID.app.Activity; import androID.content.Intent; import androID.content.pm.ResolveInfo; import androID.os.Bundle; import androID.vIEw.Gravity; import androID.Widget.GrIDVIEw; import static com.xyz.workspace.Workspace.APP_PAGE_SIZE;  public class MainActivity extends Activity implements OnVIEwChangedListener {   private Workspace mWorkspace;  private PageIndicator mIndicator;   /** Called when the activity is first created. */  @OverrIDe  public voID onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentVIEw(R.layout.main);    mWorkspace = (Workspace) findVIEwByID(R.ID.workspace);   mIndicator = (PageIndicator) findVIEwByID(R.ID.indicator);   List<ResolveInfo> apps = loadApps();   for (int i = 0; i < Math.ceil(1.0f * apps.size() / APP_PAGE_SIZE); i++) {    GrIDVIEw grID = new GrIDVIEw(this);    grID.setNumColumns(4);    grID.setHorizontalSpacing(10);    grID.setVerticalSpacing(40);    grID.setpadding(30,50,30,20);    grID.setGravity(Gravity.CENTER);    grID.setAdapter(new GrIDAdapter(this,apps,i));    mWorkspace.addVIEw(grID);   }   mWorkspace.setonVIEwChangedListener(this);   mIndicator.setIndication(mWorkspace.getChildCount(),0);  }   private List<ResolveInfo> loadApps() {   Intent i = new Intent(Intent.ACTION_MAIN,null);   i.addcategory(Intent.category_LAUNCHER);   return getPackageManager().queryIntentActivitIEs(i,0);  }   @OverrIDe  public voID onChange(int cnt,int index) {   // Todo auto-generated method stub   mIndicator.setIndication(cnt,index);  } }

源码下载:android仿iphone主题之主菜单

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的android仿iphone主题效果的主菜单全部内容,希望文章能够帮你解决android仿iphone主题效果的主菜单所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1143611.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存