本人很喜歡機鋒市場的界面風格,無論是網頁仍是手機應用,老是能在偶然間給人眼前一亮的感受,因此一直想看看它究竟是怎麼實現的,苦於找不到有介紹的文章,只好本身來了。本文主要是基於機鋒android客戶端的0.9.5beta版本,經過反編譯來查看它的界面究竟是如何實現的,因爲能力有限,因此不少東西不必定都正確,也不必定都是機鋒市場的原始的實現,只能儘可能接近它的實現。有什麼不對的地方,還請你們多多指點啊。html
那麼就先從機鋒市場的首頁講起,先來看圖java
這個界面的內容就兩塊,一個是背景圖片,還有一個就是橫向的進度條,這個頁面特別的地方就在這個進度條上了。這種進度條咱們在不少網站或是電腦上的軟件都有見過,可是在android手機上咱們常見的仍是圓形的不斷旋轉的這種進度條,機鋒的這個進度條我在手機上仍是第一次見。那麼她是如何實現的呢...咱們先來看下它的佈局文件(反編譯出來的)android
<?xml version="1.0" encoding="UTF-8"?> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:id="@+id/iv_splashBg" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="matrix" /> <LinearLayout android:gravity="center" android:id="@+id/ll_loading" android:background="@drawable/toast_bg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="40.0dip" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"> <TextView android:id="@+id/splash_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/init_data" style="\@style/text_style_1e" /> <ProgressBar android:id="@+id/splash_loading" android:layout_width="54.0dip" android:layout_height="wrap_content" android:minHeight="18dip" android:maxHeight="18dip" android:indeterminateOnly="true" /> </LinearLayout> </RelativeLayout>
在佈局文件中沒有見到特別的控件,都是系統自帶的控件啊(事實上,當我看到機鋒的進度條的時候,我想到了兩種實現方法,一種就是幀動畫,我畫出7張圖片來,經過真動畫不斷循環播放,這個理論上應該是能夠的,不過不會ps沒實現。還有一種就是本身定義一個控件,不斷的進行重繪,來實現動畫,下面是代碼canvas
public class UserView extends View{ private Paint mPaint; private boolean flag = true; private int index = 0; private int direction = 0;//0 向右,1向左 private LoopThread loopThread; public UserView(Context context) { super(context); init(); } public UserView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public UserView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init(){ mPaint = new Paint(); mPaint.setColor(0xffC8C8C8); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int offect = 0; mPaint.setStyle(Style.FILL); for (int i = 0; i < 4; i++) { if(index==i){ mPaint.setColor(0xffFFB43C); offect = 2; }else{ mPaint.setColor(0xffC8C8C8); offect = 0; } canvas.drawRect(10 + 20*i -offect, 10 - offect, 20 + 20*i + offect, 20 + offect, mPaint); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(90, 30);//設置控件的高寬 } public void start(){ if(loopThread==null){ flag = true; loopThread = new LoopThread(); loopThread.start(); }else{ flag = false; loopThread.interrupt(); loopThread = new LoopThread(); flag = true; loopThread.start(); } } public void stop(){ if(loopThread!=null){ loopThread.interrupt(); } flag = false; } private int nextIndex(int index){ int i = 0; switch(direction){ case 0: if(index+1>3 ){ direction = 1; i = index-1; }else{ i = index+1; } break; case 1: if(index-1<0){ direction = 0; i = index+1; }else{ i = index-1; } break; } return i; } private class LoopThread extends Thread{ @Override public void run() { while(true){ try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } if(!flag) break; index = nextIndex(index); postInvalidate(); } } } }
也能實現,並且效果差很少,麻煩的地方,就是要本身控制線程。)
咱們再來看看它的源碼(改動了一些)ide
progressBar.setIndeterminateDrawable(new LoadDrawable(4, 0xffC8C8C8, 0xffFFB43C));
只是對進度條設置了圖片,關鍵點仍是在LoadDrawable這個類中(因爲反編譯後的源碼有部分亂碼,下面的源碼都是我根據它實現的大概思路本身重寫的,之後的源碼也會有相似的狀況)
public class LoadDrawable extends AnimationDrawable{ private int size = 4; private int width; private int height = 30; private Paint mPaint; private int defaultColor,currentColor; public LoadDrawable(int size,int defaultColor,int currentColor) { this.defaultColor = defaultColor; this.currentColor = currentColor; this.size = size; width = (size*2 + 1) * 10; mPaint = new Paint(); mPaint.setStyle(Style.FILL); initDrawable(); setOneShot(false); } private void initDrawable(){ for (int i = 0; i < size; i++) { addFrame(drawByIndex(i), 200); } for (int i = size-2; i > 0; i--) { addFrame(drawByIndex(i), 200); } } private Drawable drawByIndex(int index){ Bitmap b = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); int offect = 0; for (int i = 0; i < 4; i++) { if(index==i){ mPaint.setColor(currentColor); offect = 2; }else{ mPaint.setColor(defaultColor); offect = 0; } c.drawRect(10 + 20*i -offect, 10 - offect, 20 + 20*i + offect, 20 + offect, mPaint); } return new BitmapDrawable(b); } }
咱們發現事實上有點想我以前的兩種方法的結合,自定義了一個AnimationDrawable類,又本身繪製了每一幀的圖片。
這裏注意下setOneShot(false)可使動畫圖片不斷循環。oop
ok,這樣機鋒市場的首頁就大功告成了啊佈局
後面會陸續寫些機鋒市場界面的其餘實現post