android仿iphone主题效果的主菜单

这篇文章主要为大家详细介绍了android仿iphone主题效果的主菜单,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

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

      

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

闲话不多说了!

主布局:main.xml

   

第一个自定义类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, attrs, 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  SNAP_VELOCITY && mCurScreen > 0) { snapToScreen(mCurScreen - 1); } else if (velocityX <-SNAP_VELOCITY && mCurScreen  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 

这两个类的作用上面已经说了,有什么看不明白的欢迎提问,或自行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 mPackagesInfo; public GridAdapter(Context context, List 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 /* 圆角半径 */) { return getRoundCornerDrawable(ctx, mContext.getResources().getDrawable(resId), roundPX); } private Drawable getRoundCornerDrawable(Context ctx, Drawable drawable, float roundPX /* 圆角半径 */) { 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, 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, 0, width, height); final RectF rectF = new RectF(rect); paint.setColor(color); paint.setAntiAlias(true); can.drawARGB(0, 0, 0, 0); can.drawRoundRect(rectF, roundPX, roundPX, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); can.drawBitmap(bitmap, rect, 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:

   

主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 apps = loadApps(); for (int i = 0; i  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主题之主菜单

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持html中文网。

以上就是android仿iphone主题效果的主菜单的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 移动