カスタムViewで雨の落下効果を実現

14073 ワード

カスタムViewで雨の落下効果を実現
最近事は多くなくて、何かを书くことを考えて、また何を书くのが良いことを知らないで、小さい効果を実现して、娯楽して、ついでに自分も更に熟练してカスタマイズviewの描く関连する知识をおりて、くだらないことを言わないで、先に図を书きます:
一、前期分析
   ,           TextView                。                          ,          ,                  ,          。  ,     ,        。

二、テキストボックスのジッタの実現
        ,         ,       ,xml  :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#fff">
    <TextView  android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginTop="30dp" android:layout_marginLeft="30dp" android:layout_marginRight="30dp" android:background="#f60" android:clickable="true" android:textColor="#fff" android:gravity="center" android:text="hahaha" />

    <com.example.test.CustomView  android:id="@+id/v" android:layout_width="match_parent" android:layout_height="match_parent" />
    </LinearLayout>
    private TextView tv;

    tv=(TextView) findViewById(R.id.tv);
    final TranslateAnimation animation = (TranslateAnimation)AnimationUtils.loadAnimation(this, R.anim.animation);
    tv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                tv.startAnimation(animation);
            }
        });

animation.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <translate xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:fromXDelta="0" android:interpolator="@anim/cycle" android:toXDelta="10" >
    </translate>

cycle.xml:
    <cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="5" />

この実現は簡単で、みんなが見ても分かるはずです.私たちは続けます.
三、円点生成及び分散効果
ok,            ,        ,    ,        , **     ** **    **   ,        **     **    ,      。
             ,            ,         ,                   ,               。
    class Circle{

        //x      
        int x;
        //y    
        int y;
        //       
        int alpha;
        //        
        float width;
        //     
        float radius;
        //         
        Paint paint;
    }
                 ,               ,   ,       View       。
public class CustomView extends View {

    //       
    private Paint paint;
    private List<Circle> list = new ArrayList<CustomView.Circle>();
    //x   
    //     
    private Paint Circlepaint;
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.RED);

        Circlepaint = new Paint(paint);
        Circlepaint.setStyle(Paint.Style.STROKE);
    }
    @Override
    protected void onDraw(Canvas canvas) {      
        for(Circle circle:list){
            if(circle.alpha<15){
                circle.alpha = 0;
            }
            circle.paint.setAlpha(circle.alpha);
            if(circle.y >= dp2px(300)){
                circle.paint.setStrokeWidth(circle.width);
                canvas.drawCircle(circle.x, dp2px(300), circle.radius, circle.paint);
            }else{
                canvas.drawCircle(circle.x, circle.y, circle.radiusSamll, paint);
            }
        }

    }
    //    view
    public void refresh(int y){
        int x = dp2px(150);
        int cishu = new Random().nextInt(4);
        switch (cishu) {
        case 0:
            x-=dp2px(30);
            break;
        case 1:
            x+=dp2px(30);
            break;
        case 2:
            x-=dp2px(10);
            break;
        case 3:
            x+=dp2px(10);
            break;
        }
        Circle circle = new Circle();
        circle.x = x;
        circle.y = y;
        circle.radius = dp2px(60f);
        circle.alpha = 255;
        circle.radiusSamll = dp2px(10);
        circle.width = dp2px(60f);
        circle.paint = Circlepaint;//   paint
        list.add(circle);
        invalidate();
    }
    private List<Circle> tempList = new ArrayList<CustomView.Circle>();
    @Override
    public void computeScroll() {
        for(Circle circle:list){
            if(circle.y <dp2px(300)){
                circle.y+=dp2px(8);
                invalidate();
            }else{
                if(circle.alpha >= 0){
                    circle.radius+=dp2px(28);
                    circle.alpha-=10;
                    circle.width-=dp2px(15);
                    if(circle.width<0){
                        circle.width = 0;
                        circle.radius = 0;
                    }
                    invalidate();
                }else{
                    // alpha   0           
                    tempList.add(circle);
                }
            }
        }
        //            
        list.removeAll(tempList);
    }
    class Circle{
        //x    
        int x;
        //y    
        int y;
        //       
        int alpha;
        //        
        float width;
        //        
        float radius;
        //      
        float radiusSamll;
        //         
        Paint paint;
    }
    public int dp2px(float value){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, getResources().getDisplayMetrics());
    }
}

    private TextView tv;
    private CustomView cv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cv = (CustomView) findViewById(R.id.v);
        tv=(TextView) findViewById(R.id.tv);
    final TranslateAnimation animation = (TranslateAnimation)AnimationUtils.loadAnimation(this, R.anim.animation);
    tv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                tv.startAnimation(animation);
                //      
                cv.refresh(0);
            }
        });
    }

コアは、クリックするたびに1つの円点オブジェクトを作成し、集合に格納します.onDraw呼び出しのたびに、ループ集合の各オブジェクトがインタフェースに描画されます.invalidateメソッドはcomputeScrollメソッドをトリガーします.computeScrollメソッド呼び出し時に、ループは各オブジェクトの透明値が0未満かどうか、すなわち表示されないかどうかを判断します.表示されない場合は、集合から削除します.注意コレクションはループ時に削除操作が許可されないので、ループが終了した後に一括して削除する一時コレクションに入れます.
四、まとめ
   view                  ,            ,Paint,Canvas        ,              ,   。