先看ANDROID QQ截图:
[img]http://dl.iteye.com/upload/attachment/300124/ba1e6613-cd88-3a02-90fe-dc29425571a4.png[/img]
再看DEMO截图:
[img]http://dl.iteye.com/upload/attachment/300126/18763953-75f0-34fd-92b8-d68a6a255d85.png[/img]
[img]http://dl.iteye.com/upload/attachment/300128/38a88b09-fd6c-3f50-aa82-7ae10b7c83d8.png[/img]
直接看代码:
[color=red]NewLayOut 类 继承 LinearLayout[/color],因为需要在LinearLayout里面画图
编写的过程中发现一点问题:
第一:画图与循环同步的问题
如果把 [color=red]if(this.mSyn)[/color] 这段去掉 看图:
[img]http://dl.iteye.com/upload/attachment/300114/bc7af164-ed32-3d3c-9926-3db6328f1c83.png[/img]
就是while循环好多次之后,onDraw才执行一次。猜想onDraw在上一次未执行完之前是不会被执行第二次的(onDraw好像开了一个新线程画图,但看SDK源码实现没看出个端儿。),所以需要做一个这样的同步。这里是继承LinearLayout的,不知道直接继承View会不会出现这种情况。上面的程序,onDraw执行完的时间大概在Thread.sleep(35)这么多时间。
看看把 [color=red]if(this.mSyn)[/color] 加上去后的打印数据 看图:
[img]http://dl.iteye.com/upload/attachment/300116/069f4aa3-e207-33f9-a42c-0c3140f1d386.png[/img]
第二:把移动的运算部份run.run();的方法直接放到onDraw里面运算
这样做的话,发觉移动的侦数比较底下,分析了一下原因。首先上面讲的,因为onDraw在上一次未画完图之前,第二次是不会运行的。而while循环又无视onDraw方法未执行完毕。所以在onDraw未执行完毕的过程中。运行run.run(),把下一次移动的数据准备好了。所以侦数就稍有上升了。
最后附上DEMO的源码: [url=http://dl.iteye.com/topics/download/66bd15b9-8bda-30ed-a1f8-c07079d39970]test3.rar[/url]
如上描述,有不正确的地方,请指教。谢谢。。
完毕。
有关ANDROID QQ的一些实现方法,请听下回分解。
[img]http://dl.iteye.com/upload/attachment/300124/ba1e6613-cd88-3a02-90fe-dc29425571a4.png[/img]
再看DEMO截图:
[img]http://dl.iteye.com/upload/attachment/300126/18763953-75f0-34fd-92b8-d68a6a255d85.png[/img]
[img]http://dl.iteye.com/upload/attachment/300128/38a88b09-fd6c-3f50-aa82-7ae10b7c83d8.png[/img]
直接看代码:
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);
}
}
}
[color=red]NewLayOut 类 继承 LinearLayout[/color],因为需要在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);
}
}
}
如果把 [color=red]if(this.mSyn)[/color] 这段去掉 看图:
[img]http://dl.iteye.com/upload/attachment/300114/bc7af164-ed32-3d3c-9926-3db6328f1c83.png[/img]
就是while循环好多次之后,onDraw才执行一次。猜想onDraw在上一次未执行完之前是不会被执行第二次的(onDraw好像开了一个新线程画图,但看SDK源码实现没看出个端儿。),所以需要做一个这样的同步。这里是继承LinearLayout的,不知道直接继承View会不会出现这种情况。上面的程序,onDraw执行完的时间大概在Thread.sleep(35)这么多时间。
看看把 [color=red]if(this.mSyn)[/color] 加上去后的打印数据 看图:
[img]http://dl.iteye.com/upload/attachment/300116/069f4aa3-e207-33f9-a42c-0c3140f1d386.png[/img]
第二:把移动的运算部份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的源码: [url=http://dl.iteye.com/topics/download/66bd15b9-8bda-30ed-a1f8-c07079d39970]test3.rar[/url]
如上描述,有不正确的地方,请指教。谢谢。。
完毕。
有关ANDROID QQ的一些实现方法,请听下回分解。