您好,登錄后才能下訂單哦!
利用WindowManager簡單實現了顯示歌詞的效果~
通過程序對窗口服務有一定的了解,知識點大概為:
理解View及其子類的實現方法,程序中用到textview作為顯示,作為拓展,我們知道textview繼承自view類,view類能實現的onTouchEvent()和onDraw(Canvas canvas)方法textview也可以實現。WindowManager.LayoutParams 類的使用,如何將tv進行更新(對UI線程的理解),最后把textview顯示到窗口中。
TextView的相關代碼:
public class GeTextView extends TextView { private final String TAG = GeTextView.class.getSimpleName(); public static WindowManager.LayoutParams params = new WindowManager.LayoutParams(); private float sX,sY,x,y; public static int BAR = 25; private String str; private float f1 = 0.0f ,f2 = 0.01f; private Handler handler; WindowManager wm = (WindowManager) getContext().getApplicationContext().getSystemService(getContext().WINDOW_SERVICE); public GeTextView(Context context) { super(context); str = "再累也要開心D~~,學習ing~~"; this.setBackgroundColor(Color.argb(90, 150, 150, 150)); } public boolean onTouchEvent(MotionEvent event){ /**注意getRawX和getX之間的區別*/ x = event.getRawX(); y = event.getRawY() - BAR; switch(event.getAction()){ case MotionEvent.ACTION_DOWN: sX = event.getX(); sY = event.getY(); break; case MotionEvent.ACTION_MOVE: params.x = (int) (x - sX); params.y = (int) (y - sY); wm.updateViewLayout(this, params); break; case MotionEvent.ACTION_UP: params.x = (int) (x - sX); params.y = (int) (y - sY); wm.updateViewLayout(this, params); sX = sY = 0; break; } return true; } protected void onDraw(Canvas canvas){ super.onDraw(canvas); f1 += 0.001f; f2 += 0.001f; if(f2 > 1.0){ f1 = 0.0f; f2 = 0.01f; } this.setText(""); float len = this.getTextSize() * str.length(); Shader shader = new LinearGradient(0, 0, len, 0, new int[] { Color.YELLOW, Color.GREEN }, new float[]{f1, f2}, TileMode.CLAMP); Paint p = new Paint(); p.setShader(shader); p.setTypeface(Typeface.DEFAULT_BOLD); canvas.drawText(str, 0, 12, p); } private Runnable update = new Runnable(){ public void run(){ /**刷新tv,放在UI線程的Runnable每隔5ms執行一次*/ GeTextView.this.postInvalidate(); handler.postDelayed(update, 5); } }; }
************
懸浮窗始終顯示在最頂層
onTouchEvent方法下關于MotionEvent的3個action分別代表:手指落下,手指一動和手指離開屏幕的事件。onDraw方法設置Shader類來實現TextView的漸變,int[]數組定義參與漸變效果的顏色幾個,float[]定義每個顏色處于漸變的相對位置。postDelayed()方法把傳給它的指定Runnable在指定時間下執行。
主窗口:
public class GeciActivity extends Activity { private Button click; private GeTextView tv = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); click =(Button) findViewById(R.id.click); click.setOnClickListener(new OnClickListener(){ public void onClick(View v) { if(tv != null && tv.isShown()){ WindowManager wm = (WindowManager)getApplicationContext().getSystemService(GeciActivity.this.WINDOW_SERVICE); wm.removeView(tv); } showWindow(); } }); } public void showWindow(){ Rect rect = new Rect(); /**獲得顯示(電量信息)等的窗口*/ getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); /**保證窗口在上面的裝飾窗口之下*/ GeTextView.BAR =rect.top; WindowManager wm = (WindowManager)getApplicationContext().getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams params = GeTextView.params; /**設置顯示tv窗口的參數*/ params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; params.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE; params.width = WindowManager.LayoutParams.FILL_PARENT; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.alpha = 80; params.gravity = Gravity.LEFT|Gravity.TOP; params.x = 0; params.y = 0; tv = new GeTextView(GeciActivity.this); /**在窗口加入tv*/ wm.addView(tv, params); } }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。