編輯:關於Android編程
下面的示例是仿QQ音樂之類的歌詞欄,可以進行拖動和隱藏,代碼如下:
MainActivity:
package com.home.danglingactivity; import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private MyTextView tv; private Button btn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.main_btn); btn.setOnClickListener(this); } @Override public void onClick(View v) { if (tv != null && tv.isShown()) { hide(); } else { show(); } } /** * 隱藏顯示歌詞的TextView */ private void hide() { WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); wm.removeView(tv); btn.setText("顯示歌詞"); } /** * 顯示懸浮的TextView */ private void show() { Rect frame = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); MyTextView.TOOL_BAR_HIGH = frame.top; WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); WindowManager.LayoutParams params = MyTextView.params; 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; // 設置x、y初始值 params.x = 0; params.y = wm.getDefaultDisplay().getHeight(); tv = new MyTextView(MainActivity.this); wm.addView(tv, params); btn.setText("隱藏歌詞"); } @Override protected void onDestroy() { WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); if (tv != null && tv.isShown()) { wm.removeView(tv); } super.onDestroy(); } }
MyTextView:
package com.home.danglingactivity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Shader; import android.graphics.Shader.TileMode; import android.graphics.Typeface; import android.view.MotionEvent; import android.view.WindowManager; import android.widget.TextView; public class MyTextView extends TextView { private final String TAG = MyTextView.class.getSimpleName(); public static int TOOL_BAR_HIGH = 0; public static WindowManager.LayoutParams params = new WindowManager.LayoutParams(); private float startX; private float startY; private float x; private float y; private String text = "我是不是你最疼愛的人,你為什麼不說話,握住是你冰冷的手動也不動讓我好難過";; private float float1 = 0.0f; private float float2 = 0.01f; WindowManager wm = (WindowManager) getContext().getApplicationContext() .getSystemService(Context.WINDOW_SERVICE); public MyTextView(Context context) { super(context); this.setBackgroundColor(Color.argb(100, 140, 160, 150)); } @Override public boolean onTouchEvent(MotionEvent event) { // 觸摸點相對於屏幕左上角坐標 x = event.getRawX(); y = event.getRawY() - TOOL_BAR_HIGH; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = event.getX(); startY = event.getY(); break; case MotionEvent.ACTION_MOVE: updatePosition(); break; case MotionEvent.ACTION_UP: updatePosition(); startX = startY = 0; break; } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float1 += 0.001f; float2 += 0.001f; if (float2 > 1.0) { float1 = 0.0f; float2 = 0.01f; } this.setText(""); float len = this.getTextSize() * text.length(); Shader shader = new LinearGradient(0, 0, len, 0, new int[] { Color.YELLOW, Color.RED }, new float[] { float1, float2 }, TileMode.CLAMP); Paint p = new Paint(); p.setShader(shader); p.setTypeface(Typeface.DEFAULT_BOLD); canvas.drawText(text, 0, 10, p); } /** * 更新浮動窗口位置參數 */ private void updatePosition() { // View的當前位置 params.x = (int) (x - startX); params.y = (int) (y - startY); wm.updateViewLayout(this, params); } }
布局xml:
權限:
經過學習,我們知道Volley的架構如下:從架構上我們可以看到,volley有設置緩存機制,當找不到數據緩存或數據緩存過期時,才會聯網獲取新的數據。Volley 本身有緩
Android Service是分為兩種: 本地服務(Local Service): 同一個apk內被調用 遠程服務(Remote Service):被另一個apk調
上一篇文章中我們講解了App的數據統計,其主要分為兩種:使用第三方服務統計和自身實現數據統計。一般而言我們使用第三方統計服務已經可以很好的滿足我們的也無需求了,只是部分數
在做搜芽的過程中,發現那個外包人緣做的不行,因為啟動的時候會停頓,然後白屏一會,聯想到幾個月前我在我的三僚企業通信軟件裡面拉起9K-Mail的時候也會黑屏,所以決定學習一