Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1130973
  • 博文数量: 276
  • 博客积分: 8317
  • 博客等级: 少将
  • 技术积分: 2329
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-12 08:17
个人简介

http://ads.buzzcity.net/adpage.php?partnerid=40096

文章分类

全部博文(276)

文章存档

2013年(1)

2012年(38)

2011年(102)

2010年(85)

2009年(45)

2008年(5)

分类: 嵌入式

2010-10-07 13:54:47

先看ANDROID QQ截图: 
 
再看DEMO截图: 
 
 

直接看代码: 

public class test3 extends Activity {
    
    private NewLayOut layout;
    
    private myThread mThread;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
        layout = (NewLayOut) inflater.inflate(R.layout.move, null);
        
        ImageView button = (ImageView)layout.findViewById(R.id.ImageView01);
        button.setOnClickListener(mClickListener);
        ImageView button2 = (ImageView)layout.findViewById(R.id.ImageView02);
        button2.setOnClickListener(mClickListener);
        ImageView button3 = (ImageView)layout.findViewById(R.id.ImageView03);
        button3.setOnClickListener(mClickListener);
        
        this.setContentView(layout);
    }
    
    private View.OnClickListener mClickListener = new View.OnClickListener() {
        
        public void onClick(View v) {
            startMove(v);
        }
    };
    
    private void startMove(View v)
    {
        stopThread();//停止之前的线程

        mThread = new myThread(v);
        mThread.start();
    }
    
    private void stopThread()
    {
        if (mThread != null)
        {
            try
            {
                layout.mIsStop = true;
                mThread.join();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    
    class myThread extends Thread
    {
        private View mView;
        
        public myThread(View v){ this.mView = v; }
        
        public void run() {
            layout.doWork(this.mView);
        }
        
    }
}



NewLayOut 类 继承 LinearLayout,因为需要在LinearLayout里面画图 

package test3.program;

import android.content.Context;

import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;

public class NewLayOut extends LinearLayout {

    private static final short SPEED = 15;
    
    private Context mContext;
    private Rect mNowRect;//当前的区域

    private Rect mEndRect;//结束的区域

    private BitmapDrawable mSelecter;//移动的半透明背景bitmaip

    private boolean mSyn = false;//循环和onDraw同步

    public boolean mIsStop = false;//是否到达指定区域

    
    public NewLayOut(Context context) {
        super(context);
        init(context);
    }
    
    public NewLayOut(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    
    private void init(Context context)
    {
        mContext = context;
        mSelecter = new BitmapDrawable(
                BitmapFactory.decodeResource(mContext.getResources(),
                        R.drawable.topbar_select));
        mNowRect = new Rect();
        mEndRect = new Rect();
    }
    
    protected void onLayout(boolean paramBoolean, int paramInt1, int paramInt2, int paramInt3, int paramInt4)
    {
        super.onLayout(paramBoolean, paramInt1, paramInt2, paramInt3, paramInt4);
        this.getChildAt(0).getHitRect(mNowRect);//取得第一个控制区域作为起始区域

    }
    
    /**
     *
     * @param v 目标控件
     */

    public void doWork(View v)
    {
        v.getHitRect(this.mEndRect);
        
        if (this.mNowRect.right < this.mEndRect.right)
        {
            work(new RunForword()
            {
                public void run()
                {
                    mNowRect.left += SPEED;//每次左边移动15格

                    mNowRect.right += SPEED;//每次右边移动15格

                    
                    System.out.println("is run run run");
                    
                    if (mNowRect.right >= mEndRect.right)//如果移动超出或等于目标区域

                        ReachRect();
                }
            });
        }
        else if(this.mNowRect.right > this.mEndRect.right)
        {
            work(new RunForword()
            {
                public void run()
                {
                    mNowRect.left -= SPEED;//每次左边移动15格

                    mNowRect.right -= SPEED;//每次右边移动15格

                    
                    if (mNowRect.right <= mEndRect.right)//如果移动超出或等于目标区域

                        ReachRect();
                }
            });
        }
    }
    
    private void work(RunForword run)
    {
        this.mIsStop = false;
        while(!this.mIsStop)
        {
            if(this.mSyn)//画图与循环同步

            {
                run.run();
                System.out.println("is running!");
                this.mSyn = false;
                this.postInvalidate();
                //Thread.sleep(35);

            }
        }
    }
    
    /**
     * 到达目的地
     */

    private void ReachRect()
    {
        mNowRect.left = mEndRect.left;
        mNowRect.right = mEndRect.right;
        mIsStop = true;
    }
    
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        
        mSelecter.setBounds(mNowRect);
        mSelecter.draw(canvas);
        this.mSyn = true;

        System.out.println("is ondraw");
    }
    
    public interface RunForword
    {
        void run();
    }
}


编写的过程中发现一点问题: 

第一:画图与循环同步的问题 

private void work(RunForword run)
    {
        this.mIsStop = false;
        while(!this.mIsStop)
        {
            if(this.mSyn)//画图与循环同步

            {
                run.run();
                System.out.println("is running!");
                this.mSyn = false;
                this.postInvalidate();
                //Thread.sleep(35);

            }
        }
    }


如果把 if(this.mSyn) 这段去掉 看图: 

 

就是while循环好多次之后,onDraw才执行一次。猜想onDraw在上一次未执行完之前是不会被执行第二次的(onDraw好像开了一个新线程画图,但看SDK源码实现没看出个端儿。),所以需要做一个这样的同步。这里是继承LinearLayout的,不知道直接继承View会不会出现这种情况。上面的程序,onDraw执行完的时间大概在Thread.sleep(35)这么多时间。 

看看把 if(this.mSyn) 加上去后的打印数据 看图: 

 

第二:把移动的运算部份run.run();的方法直接放到onDraw里面运算 


private void work(RunForword run)
    {
        this.mIsStop = false;
        while(!this.mIsStop)
        {
            if(this.mSyn)//画图与循环同步

            {

                System.out.println("is running!");
                this.mSyn = false;
                this.postInvalidate();
                //Thread.sleep(35);

            }
        }
    }
protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        run.run();//大概时这个意思。。当实这样实写是不行的。

        mSelecter.setBounds(mNowRect);
        mSelecter.draw(canvas);
        this.mSyn = true;

        System.out.println("is ondraw");
    }


这样做的话,发觉移动的侦数比较底下,分析了一下原因。首先上面讲的,因为onDraw在上一次未画完图之前,第二次是不会运行的。而while循环又无视onDraw方法未执行完毕。所以在onDraw未执行完毕的过程中。运行run.run(),把下一次移动的数据准备好了。所以侦数就稍有上升了。 

最后附上DEMO的源码:  

如上描述,有不正确的地方,请指教。谢谢。。 

完毕。 
阅读(710) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~