⑴ 在android中按鈕共分為幾種
從控制項來說分為2種:button(一般按鈕)和ImageButton(圖片按鈕);
但是大部分時候,開發者是可以通過各種方式自定義按鈕,這樣的話,界面呈現出來的按鈕是多種多樣的;
TextView,view等等,很多控制項其實都可以拿來當按鈕使用;
此外,還有包括ToggleButton,單選按鈕,多選按鈕等這些都屬於是功能比較專一的特殊按鈕了;
我想你只有對android比較了解的情況下,才可能理解深一些吧!
⑵ android 五星打分控制項星星大小怎麼控制
由於Android自身的星星評分控制項樣式可以改,但是他的大小不好調整的缺點,只能用small normal這樣的style調整,自定義不強,因此擊發了我自定義星星控制項的慾望。
星星評分控制項的設計,大體規劃為:
需要兩張圖片,一顆亮星星,一顆空星星;(當然圖片不一定是星星,其他圖片也可以,現在實驗就用星星就好了)星星數量,間距可以自定義,星星的最小步進為0.1,在用戶使用的時候與Android自帶的方法一樣。
星星控制項大體分為兩層,第一層空星星,第二層亮星星,第一層固定,第二層動態繪制,這樣就可以實現評分。
在畫星星的時候,由於在xml得出回來的對象是drawable,不必再轉換為bitmap繪制,故直接繪制drawable,並且提升效率。
繪制drawable需要兩個方法就夠了
1、設置繪制到那裡:
setBounds(int left ,int top , int right ,int bottom);
2、繪制:
draw(Canvas canvas);
設置錯誤setBounds會導致繪制變形:
把setbounds設置好後就一切正常:
經過一個for循環,五顆空星星就出來了,哈哈
for (int i = 0;i < starCount;i++) {
starEmptyDrawable.setBounds(starSize * i, 0, starSize * (i + 1), starSize);
starEmptyDrawable.draw(canvas);
}
for (int i = 0;i < starCount;i++) {
starEmptyDrawable.setBounds(starSize * i, 0, starSize * (i + 1), starSize);
starEmptyDrawable.draw(canvas);
}
for (int i = 0;i < starCount -1;i++) {
starFillDrawable.setBounds(starSize * i, 0, starSize * (i + 1), starSize);
starFillDrawable.draw(canvas);
}
上面幾行代碼成功強行裝成了一個評了4分的
現在,顯示幾顆幾顆的星星無壓力,但是我們目標是需要步進為0.1的星星。
But
經過一系列的實驗,發現Drawable對象沒有能指定繪制需要的部分,也就是不能繪制半顆星星(反正找不到,找到可以評論告訴我),然後就採用了折中的方法,把Drawable對象變為Bitmap這樣就好辦了,再利用BitmapShader,想繪制多少就繪制多上(就是實現0.1步進),下面為1/3顆的效果:
轉換方法:
private Bitmap drawableToBitmap(Drawable drawable)
{
if (drawable == null)return null;
Bitmap bitmap = Bitmap.createBitmap(starSize, starSize, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, starSize, starSize);
drawable.draw(canvas);
return bitmap;
}
把Bitmap轉換為畫筆繪制:
paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(starFillBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
在ondraw()方法繪制(三分之一個)
canvas.drawRect(0,0,starSize/3,starSize,paint);
原理就是這樣,剩下就是邏輯問題了,以下為星星控制項代碼:
package com.dming.starbar;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* Created by DMing on 2016/7/18.
*
*/
public class StarBar extends View{
private int starDistance = 0; //星星間距
private int starCount = 5; //星星個數
private int starSize; //星星高度大小,星星一般正方形,寬度等於高度
private float starMark = 0.0F; //評分星星
private Bitmap starFillBitmap; //亮星星
private Drawable starEmptyDrawable; //暗星星
private OnStarChangeListener onStarChangeListener;//監聽星星變化介面
private Paint paint; //繪制星星畫筆
private boolean integerMark = false;
public StarBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public StarBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
/**
* 初始化UI組件
*
* @param context
* @param attrs
*/
private void init(Context context, AttributeSet attrs){
setClickable(true);
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RatingBar);
this.starDistance = (int) mTypedArray.getDimension(R.styleable.RatingBar_starDistance, 0);
this.starSize = (int) mTypedArray.getDimension(R.styleable.RatingBar_starSize, 20);
this.starCount = mTypedArray.getInteger(R.styleable.RatingBar_starCount, 5);
this.starEmptyDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starEmpty);
this.starFillBitmap = drawableToBitmap(mTypedArray.getDrawable(R.styleable.RatingBar_starFill));
mTypedArray.recycle();
paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(starFillBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
}
/**
* 設置是否需要整數評分
* @param integerMark
*/
public void setIntegerMark(boolean integerMark){
this.integerMark = integerMark;
}
/**
* 設置顯示的星星的分數
*
* @param mark
*/
public void setStarMark(float mark){
if (integerMark) {
starMark = (int)Math.ceil(mark);
}else {
starMark = Math.round(mark * 10) * 1.0f / 10;
}
if (this.onStarChangeListener != null) {
this.onStarChangeListener.onStarChange(starMark); //調用監聽介面
}
invalidate();
}
/**
* 獲取顯示星星的數目
*
* @return starMark
*/
public float getStarMark(){
return starMark;
}
/**
* 定義星星點擊的監聽介面
*/
public interface OnStarChangeListener {
void onStarChange(float mark);
}
/**
* 設置監聽
* @param onStarChangeListener
*/
public void setOnStarChangeListener(OnStarChangeListener onStarChangeListener){
this.onStarChangeListener = onStarChangeListener;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(starSize * starCount + starDistance * (starCount - 1), starSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (starFillBitmap == null || starEmptyDrawable == null) {
return;
}
for (int i = 0;i < starCount;i++) {
starEmptyDrawable.setBounds((starDistance + starSize) * i, 0, (starDistance + starSize) * i + starSize, starSize);
starEmptyDrawable.draw(canvas);
}
if (starMark > 1) {
canvas.drawRect(0, 0, starSize, starSize, paint);
if(starMark-(int)(starMark) == 0) {
for (int i = 1; i < starMark; i++) {
canvas.translate(starDistance + starSize, 0);
canvas.drawRect(0, 0, starSize, starSize, paint);
}
}else {
for (int i = 1; i < starMark - 1; i++) {
canvas.translate(starDistance + starSize, 0);
canvas.drawRect(0, 0, starSize, starSize, paint);
}
canvas.translate(starDistance + starSize, 0);
canvas.drawRect(0, 0, starSize * (Math.round((starMark - (int) (starMark))*10)*1.0f/10), starSize, paint);
}
}else {
canvas.drawRect(0, 0, starSize * starMark, starSize, paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
if (x < 0) x = 0;
if (x > getMeasuredWidth()) x = getMeasuredWidth();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
setStarMark(x*1.0f / (getMeasuredWidth()*1.0f/starCount));
break;
}
case MotionEvent.ACTION_MOVE: {
setStarMark(x*1.0f / (getMeasuredWidth()*1.0f/starCount));
break;
}
case MotionEvent.ACTION_UP: {
break;
}
}
invalidate();
return super.onTouchEvent(event);
}
/**
* drawable轉bitmap
*
* @param drawable
* @return
*/
private Bitmap drawableToBitmap(Drawable drawable)
{
if (drawable == null)return null;
Bitmap bitmap = Bitmap.createBitmap(starSize, starSize, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, starSize, starSize);
drawable.draw(canvas);
return bitmap;
}
}
attrs的文件:
XML的使用方式:
⑶ android進度條上的小球怎麼設置
謂進度條、滑動條和評分控制項,在手機應用中,相信你見過載入游戲時、更新應用時等情況,屏幕出現一條進度欄,這里稱之為進度條;當你調節音量時出現的這里即稱作滑動條;而評分控制項,當你在淘寶給賣家評價時出現的類似5星評價,這里即稱作評分控制項,下面將分別詳細說明這三種控制項的基礎使用方法。
工具/原料
eclipse
一、ProgressBar進度條控制項
1
首先ProgressBar進度條給出了兩種樣式,分別是progressBarStyleLarge和progressBarStyleHorizontal,此次主要以progressBarStyleHorizontal水平進度條為例講解,可在視圖布局Form Widgets中找到,其布局代碼和布局演示示例如下。
2
ProgressBar進度條需要創建一個繼承AsyncTask抽象類的Activity,並重寫doInBackground和onProgressUpdate方法,來實現進度條的基礎功能,在此之前確保已經創建了Acticity並獲取了ProgressBar控制項。其代碼如下:
3
增加按鈕創建點擊事件使進度條可以實現功能,並設置最大數值100。其代碼如下。
END
二、SeekBar滑動條控制項
1
首先將SeekBar滑動條的View寫出來,具體代碼和樣式如下。
2
然後調用SeekBar控制項,並設置總進度大小和設置監聽事件,以便對滑動條後續操作。和ProgressBar進度條一樣,用到了setMax方法來確定大小。另外還用到了setOnSeekBarChangeListener進行監聽滑動條的事件狀態。相關代碼如下:
END
三、RatingBar評分控制項
RatingBar評分控制項和SeekBar滑動條控制項類似,首先還是先來把View視圖寫好,但要注意其中有一個屬性,android:numStars="6",表示總分是6分,代碼和樣式如下:
然後同樣再在Activity中調用RatingBar控制項,並使用setOnRatingBarChangeListener方法來測試監聽評分的狀態。相關代碼如下:
最後針對如System.out.println("-->"+rating);這個形式,這個測試方法,可以過濾的多餘的無用LogCat信息,進而方便我們測試。以下是測試信息。簡單明了。
步驟閱讀
⑷ Android之自定義控制項
一、簡單自定義控制項MyButton
每一個控岩侍燃件都是一個java類,有對應的代碼,只要你能正確的編寫java代碼,那麼電腦培訓http://www.kmbdqn.cn/發現可以創造出符合你需求的控制項,即自定義控制項。
1.通過繼承的方式,創建自定義控制項
通過繼承一個現有的控制項,覆蓋其界面的呈現
通過繼承一個包含若乾子控制項的布局
通過繼承一個現有的控制項,覆蓋某個響應事件
繼承一個View來完整自定義一個心控制項
2.使你的自定義控制項繼承自某個最接近的Android控制項,必須是public
一般都會調用父類的構造方法,注意一般有三個構造方法
覆蓋原來控制項的方法,注意是否要再調用super中的方法
在XML中以類全名的方式引用此控制項
二、復雜自定義控制項MyLogin
需要設計包含一組控制項的自定義控制項就需要用到復雜的自定義控制項談脊
1)使得你的自定義控制項繼承自某個接近的布局
2)正確的實現構造方法:構造方法中實例化目標布局,同時查找到各個子布局
3)添加相應的響應代碼來修改屬性,使得外部能訪問布局中的子控制項
4)在XML中以類全粗虛名的方式引用此控制項,完整的包名+類名。
⑸ android ratingbar怎麼設置半個星
RatingBar是基於SeekBar(拖動條)和ProgressBar(狀態條)的擴展,用星形來顯示等級評定,在使用默認RatingBar時,用戶可以通過觸摸/拖動/按鍵(比如遙控器)來設置評分,RatingBar自帶有兩種模式,一個小風格ratingBarStyleSmall,大風格為ratingBarStyleIndicator,大的只適合做指示,不適用與用戶交互。
黃色星形為自定義RatingBar
小綠色為自帶的ratingBarStyleSmall
大綠色為自帶的ratingBarStyleIndicator
通過設置style="XXXXXXXXXXXXX"進行設置切換(比如:style="?android:attr/ratingBarStyleIndicator")
自定義RatingBar需要注意的地方
一般情況下,系統自帶的RatingBar是遠遠無法滿足開發需求的,我們根據圖片自定一個RatingBar,在開始實現自定義RatingBar之前,順帶說一下res目錄下圖片放置目錄的區別:
在android sdk 1.5版本之前res目錄下面只有一個drawable一個目錄,在android sdk 1.6版本以後就出現了三個目錄,分別是drawable-hdpi、drawable-ldpi、drawable-mdpi、drawable-xhdpi,
(1)drawable-hdpi裡面存放高解析度的圖片,如WVGA(480x800),FWVGA(480x854)
(2)drawable-mdpi裡面存放中等解析度的圖片,如HVGA(320x480)
(3)drawable-ldpi裡面存放低解析度的圖片,如QVGA(240x320)
(4)drawable-xhdpi裡面存放超大解析度的圖片,至少960dp x 720dp
由於我們自定義實現的RatingBar裡面使用到的星形圖片解析度比較低,所以一般情況下,我們把圖片放到drawable-mdpi或者drawable-ldpi裡面。
自定義RatingBar的實現過程
首先,根據圖片自定一個RatingBar的背景條,和圖片放到同一個目錄下面(比如drawable-mdpi),room_rating_bar.xml
?
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+android:id/background"
android:drawable="@drawable/star1"></item> <span></span>
<item android:id="@+android:id/secondaryProgress"
android:drawable="@drawable/star1"></item>
<item android:id="@+android:id/progress"
android:drawable="@drawable/star2"></item>
</layer-list>
backgroud:是用來填充背景圖片的,和進度條非常類似,當我們設置最高評分時(android:numStars),系統就會根據我們的設置,來畫出以星星為單位的背景(假如android:numStars="5",就會畫出5顆灰色的星星)
progress:是用來在背景圖片基礎上進行填充的指示屬性(和進度條類似,第一進度位置)
secondaryProgress:同progress一樣屬於第二進度位置(如果不定義這個,進度條拖動,每次就畫出一整顆星星(亮),第二進度(暗)沒有覆蓋掉第一進度之後的位置,從左往右是拖不出來N.5顆星星的,這樣評分效果就不完整)
其次,通過開始介紹,我們知道RatingBar的樣式是通過style來切換的,在android中,我們可以通過在styles.xml文件中通過設置style屬性,來繼承我們需要自定控制項類型,如下styles.xml
?
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="roomRatingBar" parent="@android:style/Widget.RatingBar">
<item name="android:progressDrawable">@drawable/room_rating_bar</item>
<item name="android:minHeight">16dp</item>
<item name="android:maxHeight">16dp</item>
</style>
</resources>
通過parent屬性來選擇繼承的父類,我們這里繼承RatingBar類。
重新定義progressDrawable屬性(RatingBar的背景條,和我們在首先裡面介紹的那樣)
maxHeight和minHeight可以根據我們圖片像素或者其他參考值來設定。
最後,在我們需要用到RatingBar的xml配置文件裡面添加RatingBar控制項。
main.xml
?
<RatingBar
android:id="@+id/room_ratingbar"
style="@style/roomRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:rating="4"
android:layout_marginLeft="10dp" >
</RatingBar>
⑹ Android 自定義控制項 layout
Android 繪制流程
View :View主要執行layout方法,使用 serFrame 方法來設置本身 View 的四個頂點的位置,確定View本身的位置。
ViewGroup :ViewGroup主要執行onLayout方法,遞歸遍歷所有子View,確定子View的位置。
我們來看ViewRootImpl中的 performLayout() 方法
看到這里,那host.getMeasuredWidth() / host.getMeasuredHeight()是什麼?它是直接調用View中的方法,其實就是經過measure後的DecorView的測量寬度和高度。在 Android 自定義控制項 measure 中有說明。
2.3.2.1 我們先來看ViewGroup中的 layout() 方法
ViewGroup裡面的layout最終會調入到父類View中的layout,View的layout後面講解。這里可以先告訴大家,最終會調用View的onLayout方法,而ViewGroup的onLayout是抽象方法,所以它的子類LinearLayout必須要實現。
2.3.2.2 我們再來看LinearLayout中的 onLayout() 方法。
2.3.2.3 挑一個縱向的吧,我們再來看LinearLayout中的 layoutVertical() 方法。
2.3.2.4 我們再來看LinearLayout中的 setChildFrame() 方法。
又一次回到了View的layout方法,接下來就看View分發的layout。
我們先來看View中的 layout() 方法。
我們先來看View中的 onLayout() 方法。
空空如也,其實View的布局由父容器決定,所以空實現是正常的,當然也可以在自定義View中進行更改。
《Android 視圖模塊 全家桶》
Android開發之自定義控制項(二)---onLayout詳解
自定義View Layout過程 - 最易懂的自定義View原理系列(3)