類似window7的氣泡屏保的自定義view

這個只能做來玩玩兒,沒有太多的使用價值,看著好玩,有密集恐懼癥的就不要玩兒了

在實現(xiàn)上主要使用了兩個自定義view

一個畫圓(使用圖片也是可以的)

一個寫位置邏輯

github鏈接

上圖

不重疊氣泡

重疊氣泡

其中有兩種狀態(tài)诅挑,一種可以重疊,一種不能重疊泛源。類似Window 7 氣泡的屏保拔妥。

一個使用兩個自定義view,一個就是一個圓圈,一個實現(xiàn)動畫达箍,邊界計算

圓圈的view
計算距離的view

在實現(xiàn)上畫圓的view簡單到其實就一個方法

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            mPaint.setStyle(painStyle);
            mPaint.setColor(color);
            mPaint.setStrokeWidth(width);
            canvas.drawCircle(mWidth/2,mHeight/2,mWidth/2-width*2,mPaint);
        }

就是一個圓圈没龙,這里其實使用圖片簡單粗暴,啥也不用寫,只是為了獲取一個圓而已

下一個view多一點邏輯

如下:

    /**
         * add view  獲取到view
         * @param view
         */
        public void addBallsView(RainBallView view){
            Balls balls=new Balls();
            balls.setRainBallView(view);
            balls.setXtag(movePos);
            balls.setYtag(movePos);
    //        balls.getRainBallView().setX(200/((int)(Math.random()*9)+1));
    //        balls.getRainBallView().setY(200/((int)(Math.random()*9)+1));
    
            mViewList.add(balls);
            addView(view);
        }

當然了有對象最好兜畸。有一個Ball的對象實現(xiàn)

邏輯代碼如下

    public void startMove(){
            for (int i = 0; i < mViewList.size(); i++) {
    
                //保證每一個小球的唯一性努释,使用對象
                Balls rainBallView= mViewList.get(i);
                //寬度判斷
    //            Log.i("x-->",rainBallView.getRainBallView().getX()+"");
    //            Log.i("y-->",rainBallView.getRainBallView().getY()+"");
    //            Log.i("w-->",screenWidth-rainBallView.getRainBallView().getWidth()+"");
    
                if(rainBallView.getRainBallView().getX()<0||rainBallView.getRainBallView().getX()>=screenWidth-rainBallView.getRainBallView().getWidth()){
                    rainBallView.setXtag(-rainBallView.getXtag());
                    //隨機數(shù)出現(xiàn)不能一次將值的正負改變碘梢,所以取最大值,否則會在邊界上抖
                    //×2為了避免是在邊界碰撞咬摇,位置移動沒辦法移出來
                    randomX=rainBallView.getXtag()*2;
                }else {
                    randomX=(int)(Math.random()*rainBallView.getXtag());
                }
                //高度判斷
                if(rainBallView.getRainBallView().getY()<0||rainBallView.getRainBallView().getY()>=screenHeight-rainBallView.getRainBallView().getHeight()){
                    rainBallView.setYtag(-rainBallView.getYtag());
                    //隨機數(shù)出現(xiàn)不能一次將值的正負改變,所以取最大值
                    //×2為了避免是在邊界碰撞煞躬,位置移動沒辦法移出來
                    randomY=rainBallView.getYtag()*2;
                }else {
                    randomY=(int)(Math.random()*rainBallView.getYtag());
                }
    
                //判斷兩個小球之間的距離肛鹏,如果相聚小于兩個的半徑值的兩倍,則接觸了恩沛,就反彈
                for (int j = 0; j < mViewList.size(); j++) {
                    //排除自己
                    if(j!=i&&isReward){
                        //x方向的距離的絕對值
                        int xTox=(int) Math.abs(rainBallView.getRainBallView().getX()-mViewList.get(j).getRainBallView().getX());
                        //y方向的距離的絕對值
                        int yToy= (int) Math.abs(rainBallView.getRainBallView().getY()-mViewList.get(j).getRainBallView().getY());
                        //兩個球的距離
                        int ballToball=rainBallView.getRainBallView().getWidth();
    //                    Log.i("xDis",xTox+"-"+ballToball+"-"+yToy);
                        //x和y方向的距離的絕對值
                        if(xTox<ballToball&&yToy<ballToball){
                            //當前的小球x方向取反
                            rainBallView.setXtag(-rainBallView.getXtag());
                            //隨機數(shù)出現(xiàn)不能一次將值的正負改變在扰,所以取最大值
                            //×2兩個小球一起移動,位移是兩倍
                            if(rainBallView.getXtag()>0){
                                randomX=(ballToball-xTox);
                            }else {
                                randomX=-(ballToball-xTox);
                            }
                            randomX= rainBallView.getXtag()*2;
                            //當前的小球y方向取反
                            rainBallView.setYtag(-rainBallView.getYtag());
                            //隨機數(shù)出現(xiàn)不能一次將值的正負改變雷客,所以取最大值
                            //×2為了避免是在邊界碰撞芒珠,位置移動沒辦法移出來
                            if(rainBallView.getYtag()>0){
                                randomY=(ballToball-yToy);
                            }else {
                                randomY=-(ballToball-yToy);
                            }
                            //×2兩個小球一起移動,位移是兩倍
                            randomY=rainBallView.getYtag()*2;
                            mViewList.get(j).setXtag(-mViewList.get(j).getXtag());
                            mViewList.get(j).setYtag(-mViewList.get(j).getYtag());
                        }
                    }
                }
                rainBallView.getRainBallView().setX(rainBallView.getRainBallView().getX()+randomX);
                rainBallView.getRainBallView().setY(rainBallView.getRainBallView().getY()+randomY);
            }
        }

注釋盡量寫的多一點搅裙,修改過部分皱卓,有一兩注釋句可能位置不對,沒啥大的影響

對于多次的繪制view部逮,使用了handler實現(xiàn)的延遲操作娜汁,實現(xiàn)運動的效果

    private Handler mHandler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                if(msg.what==1){
                    mHandler.sendEmptyMessageDelayed(1,5);
                    startMove();
                }
            }
        };

這也是比肩常用的方式。很多時候延遲都會用到handler實現(xiàn)兄朋。

使用,考入兩個自定義view,直接使用

只要是計算邊界的位置掐禁,保證小球不能出界,出界就讓它往回走颅和,分別判斷了寬高的位置

    if(rainBallView.getRainBallView().getX()<0||rainBallView.getRainBallView().getX()>=screenWidth-rainBallView.getRainBallView().getWidth()){
                    rainBallView.setXtag(-rainBallView.getXtag());
                    //隨機數(shù)出現(xiàn)不能一次將值的正負改變傅事,所以取最大值,否則會在邊界上抖
                    //×2為了避免是在邊界碰撞,位置移動沒辦法移出來
                    randomX=rainBallView.getXtag()*2;
                }else {
                    randomX=(int)(Math.random()*rainBallView.getXtag());
                }
                //高度判斷
                if(rainBallView.getRainBallView().getY()<0||rainBallView.getRainBallView().getY()>=screenHeight-rainBallView.getRainBallView().getHeight()){
                    rainBallView.setYtag(-rainBallView.getYtag());
                    //隨機數(shù)出現(xiàn)不能一次將值的正負改變峡扩,所以取最大值
                    //×2為了避免是在邊界碰撞享完,位置移動沒辦法移出來
                    randomY=rainBallView.getYtag()*2;
                }else {
                    randomY=(int)(Math.random()*rainBallView.getYtag());
                }

還有就是判斷當前繪制的小球不能和其他的小球的距離小于兩個小球的半徑和,也就是直徑的距離有额,由x和y兩個方向般又,分別判斷,實現(xiàn)位置的判斷

    //x方向的距離的絕對值
      int xTox=(int) Math.abs(rainBallView.getRainBallView().getX()-mViewList.get(j).getRainBallView().getX());
       //y方向的距離的絕對值
       int yToy= (int) Math.abs(rainBallView.getRainBallView().getY()-mViewList.get(j).getRainBallView().getY());
        //兩個球的距離
        int ballToball=rainBallView.getRainBallView().getWidth();
    //  Log.i("xDis",xTox+"-"+ballToball+"-"+yToy);
        //x和y方向的距離的絕對值
         if(xTox<ballToball&&yToy<ballToball){
        //   .......
         }        

實現(xiàn)了判斷巍佑,只剩下位置的后移茴迁。和方向的反轉(zhuǎn),這樣就是反彈效果萤衰,

其余的樣式參數(shù)也就只是簡單的設(shè)置一下就可以了

使用鏈接

xml布局中

    <com.yk.myselfview.views.RainBallLayout android:layout_width="match_parent"
                                                android:id="@+id/rain_ball_layout"
                                                android:layout_height="match_parent">
        </com.yk.myselfview.views.RainBallLayout>

頁面

    public class BallsViewActivity extends AppCompatActivity {
    
        private RainBallLayout mRainBallLayout;
    
        private List<Integer> mListColor=new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_balls_view);
            mListColor.add(Color.BLUE);
            mListColor.add(Color.BLACK);
            mListColor.add(Color.GREEN);
            mListColor.add(Color.RED);
            mListColor.add(Color.CYAN);
    
            mRainBallLayout = (RainBallLayout) findViewById(R.id.rain_ball_layout);
            for (int i = 0; i < 1; i++) {
                RainBallView rainBallView=getRainBallView();
                mRainBallLayout.addBallsView(rainBallView);
                //s是否可以相交
                mRainBallLayout.isReward(true);
                mRainBallLayout.startAmimation();
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            mRainBallLayout.stopAmimation();
        }
    
        public void addBall(View view) {
            RainBallView rainBallView = getRainBallView();
            mRainBallLayout.addBallsView(rainBallView);
        }
    
        @NonNull
        private RainBallView getRainBallView() {
            Random random=new Random();
            int color = random.nextInt(4);
            RainBallView rainBallView=new RainBallView(this);
            rainBallView.setColors(mListColor.get(color));
            rainBallView.setPainStyle(Paint.Style.STROKE);
            rainBallView.setWidth(4);
            return rainBallView;
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末堕义,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌倦卖,老刑警劉巖洒擦,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異怕膛,居然都是意外死亡熟嫩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門褐捻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掸茅,“玉大人,你說我怎么就攤上這事柠逞∶潦ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵板壮,是天一觀的道長逗鸣。 經(jīng)常有香客問我,道長绰精,這世上最難降的妖魔是什么撒璧? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮茬底,結(jié)果婚禮上沪悲,老公的妹妹穿的比我還像新娘。我一直安慰自己阱表,他們只是感情好殿如,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著最爬,像睡著了一般涉馁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上爱致,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天烤送,我揣著相機與錄音,去河邊找鬼糠悯。 笑死帮坚,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的互艾。 我是一名探鬼主播试和,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纫普!你這毒婦竟也來了阅悍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎节视,沒想到半個月后拳锚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡寻行,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年霍掺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寡痰。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡抗楔,死狀恐怖棋凳,靈堂內(nèi)的尸體忽然破棺而出拦坠,到底是詐尸還是另有隱情,我是刑警寧澤剩岳,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布贞滨,位于F島的核電站,受9級特大地震影響拍棕,放射性物質(zhì)發(fā)生泄漏晓铆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一绰播、第九天 我趴在偏房一處隱蔽的房頂上張望骄噪。 院中可真熱鬧,春花似錦蠢箩、人聲如沸链蕊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽滔韵。三九已至,卻和暖如春掌实,著一層夾襖步出監(jiān)牢的瞬間陪蜻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工贱鼻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宴卖,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓邻悬,卻偏偏與公主長得像症昏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拘悦,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容