机锋市场的界面实现1

本人很喜欢机锋市场的界面风格,无论是网页仍是手机应用,老是能在偶然间给人眼前一亮的感受,因此一直想看看它究竟是怎么实现的,苦于找不到有介绍的文章,只好本身来了。本文主要是基于机锋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

相关文章
相关标签/搜索