1. 程式人生 > >新增自定義View的Widget

新增自定義View的Widget

我們widget裡面可以使用的控制元件只有:AnalogClock,Button,Chronometer,ImageButton,mageView,ProgressBar,TextView這7種,要是想用自己自定義的view,必須在frameworks中新增自己自定義的view。

        根據AnalogClockWidget控制元件,自定義了一個DenqinAnalogClockWidget.java,路徑  vendor\mediatek\proprietary\frameworks\base\widget\java\com\mediatek\widget。程式碼順便貼出來吧

/* Copyright Statement:
 *
 * This software/firmware and related documentation ("MediaTek Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
 * the prior written permission of MediaTek inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of MediaTek Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * MediaTek Inc. (C) 2010. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
 * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
 * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
 *
 * The following software/firmware and/or related documentation ("MediaTek
 * Software") have been modified by MediaTek Inc. All revisions are subject to
 * any receiver's applicable license agreements with MediaTek Inc.
 */

package com.mediatek.widget;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.os.Handler;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RemoteViews.RemoteView;
import com.mediatek.internal.R;

import java.util.TimeZone;

/**
 * @hide
 */
@RemoteView
public class DenqinAnalogClockWidget extends View {

    private final Paint mPaint = new Paint();
    private static final float STROKE_WIDTH = 4f;
    private static final float STROKE_WIDTH_MS = 3f;
    private static final float HOUR_RADIUS_SCALE = 0.5f;
    private static final float MINUTE_RADIUS_SCALE = 0.8f;
    private static final float OFFSET_RADIUS_SCALE = 0.1f;
    private static final float RADIUS_SCALE = 0.9f;

    private Time mCalendar;
    private float mMinutes;
    private float mHour;
    private String mMonthDay;
    
    private Bitmap mBgBitmap;
    private Bitmap mHourBitmap;
    private Bitmap mMinutesBitmap;

    private boolean mAttached;
    private final Handler mHandler = new Handler();

    public DenqinAnalogClockWidget(Context context) {
        this(context, null);
    }

    public DenqinAnalogClockWidget(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DenqinAnalogClockWidget(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mCalendar = new Time();
        mPaint.setStyle(Style.STROKE);
        mPaint.setColor(Color.WHITE);
        mPaint.setAntiAlias(true);
        mPaint.setTextSize(
        		getContext().getResources().getDimension(R.dimen.month_day_size));
        
        mBgBitmap = BitmapFactory.decodeResource(
        		getContext().getResources(), R.drawable.dial_plate);
        mHourBitmap = BitmapFactory.decodeResource(
        		getContext().getResources(), R.drawable.hour);
        mMinutesBitmap = BitmapFactory.decodeResource(
        		getContext().getResources(), R.drawable.minute);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int x = (getRight() - getLeft()) / 2;
        int y = (getBottom() - getTop()) / 2;
        float xT;
        float yT = (float)y + ((float)mBgBitmap.getHeight()) / 70;
        
        canvas.setDrawFilter(new PaintFlagsDrawFilter(
        		0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        canvas.drawBitmap(mBgBitmap, 
        		x - mBgBitmap.getWidth() / 2, y - mBgBitmap.getHeight() / 2, mPaint);
        if (mMonthDay.length() == 1) {
        	xT = (float)x + ((float)mBgBitmap.getWidth()) / 7;
        } else {
        	xT = (float)x + ((float)mBgBitmap.getWidth()) / 8;
        }
        canvas.drawText(mMonthDay, xT, yT, mPaint);

        canvas.save();
        canvas.rotate(mHour / 12.0f * 360.0f, x, y);
        canvas.drawBitmap(mHourBitmap, 
        		x - mHourBitmap.getWidth() / 2, y - mHourBitmap.getHeight() / 2, mPaint);
        canvas.restore();

        canvas.save();
        canvas.rotate(mMinutes / 60.0f * 360.0f, x, y);
        canvas.drawBitmap(mMinutesBitmap, x - mMinutesBitmap.getWidth() / 2, 
        		y - mMinutesBitmap.getHeight() / 2, mPaint);
        canvas.restore();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        if (!mAttached) {
            mAttached = true;
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_TIME_TICK);
            filter.addAction(Intent.ACTION_TIME_CHANGED);
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
            getContext().registerReceiverAsUser(mIntentReceiver,
                    android.os.Process.myUserHandle(), filter, null, mHandler);
        }

        mCalendar = new Time();
        onTimeChanged();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mAttached) {
            getContext().unregisterReceiver(mIntentReceiver);
            mAttached = false;
        }
    }

    private void onTimeChanged() {
        mCalendar.setToNow();

        int hour = mCalendar.hour;
        int minute = mCalendar.minute;
        int second = mCalendar.second;
        mMonthDay = Integer.toString(mCalendar.monthDay);

        mMinutes = minute + second / 60.0f;
        mHour = hour + mMinutes / 60.0f;

        updateContentDescription(mCalendar);
    }

    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
                String tz = intent.getStringExtra("time-zone");
                mCalendar = new Time(TimeZone.getTimeZone(tz).getID());
            }

            onTimeChanged();
            invalidate();
        }
    };

    private void updateContentDescription(Time time) {
        final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
        String contentDescription = DateUtils.formatDateTime(mContext,
                time.toMillis(false), flags);
        setContentDescription(contentDescription);
    }
}

        這個自定義的view是根據AnalogClockWidget修改來的,修改了下時針、分針和錶盤。其中用到3張圖片和字型大小,資源路徑vendor\mediatek\proprietary\frameworks\base\res\res\drawable-xhdpi和vendor\mediatek\proprietary\frameworks\base\res\res\values。然後在symbols.xml中宣告一下,路徑也是vendor\mediatek\proprietary\frameworks\base\res\res\values

        然後在Widget佈局中直接引用顯示就可以了

<com.mediatek.widget.DenqinAnalogClockWidget
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
        效果圖:

        


相關推薦

Ralink RT5350:新增定義GPIO應用程式

Ralink RT5350:新增自定義GPIO應用程式 1.編寫LED應用程式,並修改相關配置檔案 1.1 新建led目錄 1.2新建led.c 1.3 編寫led.c 1.4 新建led目錄下Makefile 1.5 修改led上層目錄下的Makefile 1.6 將IO口

ArcMap新增定義工具異常 - No New Objects added

問題描述: ArcMap新增自定義工具經常會出現“No New Objects added”的異常提示 原因分析: 新增的 XX.tlb 檔案未正確註冊造成,可能原因有兩種: 1、許可權不夠導致新增失敗 2、tlb檔案編譯不正確 解決方案: 方法一、點選"ArcMap"程式圖

Apollo新增定義的環境

如果需要新增的環境不是Apollo預先定義的環境,請參照如下步驟操作: 假設需要新增的環境名稱叫sit 修改com.ctrip.framework.apollo.core.enums.Env類,在其中加入SIT列舉: public enum Env{ LOCAL, DEV, SI

009-Ambari二次開發之新增定義元件Redis(二)

上一篇我們主要介紹了Ambari新增元件的答題流程並以REDIS為例說明了流程,本篇在上一篇的基礎上,進一步完善說明流程並介紹如何給元件新增metric 掃描二維碼,關注BearData,獲取最新文章 上篇中,我們已經制作出了redis的rpm包,並重新編譯了我們修改後的Ambar

008-Ambari二次開發之新增定義元件Redis(一)

Ambari目前支援的元件有HDFS、YARN、HBase、Hive、Pig、ZooKeeper、Sqoop、Storm、Flume、Tez、Oozie、Falcon、Storm、Altas、Knox、Spark、Ranger、Mahout、Kerberos等,已經涵蓋了從大資料應用的

win10新增定義右鍵選單

如果你想實現在檔案上點選右鍵,選擇右鍵快捷方式裡一個軟體來開啟它,但是右鍵選單裡沒有這個軟體的快捷方式(比如免安裝版的UltraEdit),如下是步驟 1、“windows鍵+R”開啟執行視窗,輸入regedit,然後點選“確定”開啟登錄檔(有的家庭版的系統沒有登錄檔許可權,先升級系統吧)

vue $emit子元件傳出多個引數,如何在父元件中在接收所有引數的同時新增定義引數

前言 很多時候用$emit攜帶引數傳出事件,並且又需要在父元件中使用自定義引數時,這時我們就無法接受到子元件傳出的引數了。找到了兩種方法可以同時新增自定義引數的方法。 方法一 子元件傳出單個引數時: // 子元件 this.$emit('test',this.param) // 父元件 @test=

zabbix新增定義監控並使用本地使用者傳送報警郵件

需求說明 監控httpd的程序,並使用本地使用者傳送郵件 操作環境 zabbix服務端和客戶端均配置完成並可以正常使用,服務端安裝mailx不需要修改配置檔案 zabbix配置服務端和客戶端並新增監控 操作步驟 客戶端 ①.建立自定義監控的指令

車機開發之新增定義

S700平臺即安卓5.1.1系統新增額外的自定義鍵值按鍵: 在Android的原生系統中鍵值預設情況下是92個,從0-91;一般情況下,這些鍵值是夠用的,但是如果想擴充的話,還是需要新增新的鍵值的;像我們做車機專案的,新增新按鍵鍵值太易見了,比如將倒車檢測做成新自定義鍵值按鍵,我們需要到多個

Centos7上新增定義服務檔案並開機啟動

Ⅰ-1 寫服務檔案 [Unit]   ##服務的說明Description:描述服務After:描述服務類別 [Service]   ##服務執行引數的設定Type=forking是後臺執行的形式ExecStart為服務的具體執行命令ExecReload為重啟命令E

caffe中新增定義的layer

有兩種方式,一種是使用python layer相對簡單,另一種是使用C++。 1.python layer 參考 http://chrischoy.github.io/research/caffe-python-layer/ layer { type: 'Python' name:

chkconfig新增定義服務

1、在/etc/init.d/目錄下新建一個自定義服務的檔案如:myservice.sh 2、新增下面兩句到 #!/bin/bash 之後。 # chkconfig: 2345 10 90  # description: 這裡寫英文的服務介紹 說明:當我們使用命令 chkcon

Android原始碼新增定義系統服務

1、建立AIDL檔案 在原始碼frameworks/base/core/java/android/os/下面新增了一個ICCCService.aidl   2、將AIDL檔案放到編譯frameworks/base/Android.mk中 在frameworks/ba

Android 應用互調的實現並新增定義許可權進行安全防護

最近在做一個安全漏洞修復的工作,場景是A應用必須由B應用調起,由於涉及到元件暴露所以我們需要考慮安全的問題,最後添加了自定義許可權進行解決。 一、A應用 作為被調起者,需要暴露元件給B應用。所以A的清單檔案中要新增自定義許可權(注意:這裡的許可權級別至少是signature或者signatu

[轉]CentOS7利用systemctl新增定義系統服務

原文:https://www.cnblogs.com/saneri/p/7778756.html CentOS7自定義系統服務 CentOS7的服務systemctl指令碼存放在:/usr/lib/systemd/,有系統(system)和使用者(user)之分,需要開機不登陸就能執行的程式,存在系統服務

Android 去除Button預設陰影效果並新增定義陰影

1、首先先說一下預設的陰影效果 // Java setStateListAnimator(null); // xml android:stateListAnimator="@null" 2、自定義陰影實現的方式有很多種 a、將Button分層,將兩層的背景區分開就OK,但

資料檢驗外掛: Validate外掛 新增定義表單驗證

        jQuery.validator.addMethod("ValiPass", function(value, element,params) {         var exp =

sql 新增定義排序

Mysql : SELECT (@i:[email protected]+1) AS ind ,欄位 FROM 表名 別名, (SELECT @i:=0) t WHERE `IsDeleted` = 0; Oracle: 本就有rownum。可直接用:SELECT rownum,欄位 FROM

BJUI怎樣對input新增定義驗證規則

場景 在使用BJUI框架實現新增以及編輯功能時,要對輸入的內容進行驗證。 對於簡單的非空驗證以及是否為數字驗證,BJUI有自帶的驗證語法。 參照: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/82418214

S4 BP增強 BDT方式 新增定義螢幕 KNA1和KNVV 通用資料檢視、銷售與分銷檢視(英文)

其他參考(中文):https://blog.csdn.net/guangcong2009/article/details/80569877 網上沒找到銷售與分銷 檢視:KNVV的新增方式,發出來分享下。 1、新增銷售區域螢幕時, 直接將下步驟KNA1改為 KNVV即可。 2、螢