首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

QQ顶栏扁圆透明背景移动的实现

2012-08-28 
QQ顶栏椭圆透明背景移动的实现!先看ANDROID QQ截图:再看DEMO截图:直接看代码: public class test3 extends

QQ顶栏椭圆透明背景移动的实现!
先看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;//移动的半透明背景bitmaipprivate 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的源码: test3.rar

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

完毕。

有关ANDROID QQ的一些实现方法,请听下回分解。 1 楼 offeeyang 2010-08-28   效果不错啊 2 楼 Czero 2010-09-15   不错啊,楼主有心 3 楼 huanxisha147 2010-11-05   不错 我要深入学习  4 楼 Coding.Ghost 2010-12-16   进入高级View必须学习的东西。 5 楼 ffshow2006 2011-01-05   下回分解在哪?要是引用的给个链接啊。 6 楼 binner 2011-03-31   cool!

热点排行