androidattributeset
『壹』 android listView 顯示不全,為什麼
重寫LinearLayout顯示列表
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
/***
*
* @author FreePC
*
*/
public class LinearLayoutForListView extends LinearLayout
{
private BaseAdapter adapter;
private OnItemClickListener onItemClickListener;
/**
* 通過 java代碼 實例化
* @param context
*/
public LinearLayoutForListView(Context context)
{
super(context);
//設置LinearLayoutForListView為垂直布局,否者默認為水平布局,容易疏忽導致子項顯示不全
LinearLayoutForListView.this.setOrientation(LinearLayout.VERTICAL);
}
/**
* 此構造函數可以允許我們通過 XML的方式注冊 控制項
* @param context
* @param attrs
*/
public LinearLayoutForListView(Context context, AttributeSet attrs)
{
super(context, attrs);
LinearLayoutForListView.this.setOrientation(LinearLayout.VERTICAL);
}
/**
* 設置適配器
*
* @param adpater
*/
public void setAdapter(BaseAdapter adpater)
{
this.adapter = adpater;
bindLinearLayout();
}
/**
* 獲取適配器Adapter
*
* @return adapter
*/
public BaseAdapter getAdpater()
{
return adapter;
}
/**
* 綁定布局:將每個子項的視圖view添加進此線性布局LinearLayout中
*/
public void bindLinearLayout()
{
int count = adapter.getCount();
for (int i = 0; i < count; i++)
{
View v = adapter.getView(i, null, null);
if (i != count - 1)
{ //添加每項item之間的分割線
v = addLine(v);
}
addView(v, i);
}
setItemClickListener();
Log.v("countTAG", "" + count);
}
/**
* 添加每項item之間的分割線
*
* @param view
* @return
*/
public View addLine(View view)
{
//分割線view
View lineView = new View(view.getContext());
// 將數據從dip(即dp)轉換到px,第一參數為數據原單位(此為DIP),第二參數為要轉換的數據值
float fPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
(float) 0.5, view.getResources().getDisplayMetrics());
int iPx = Math.round(fPx);
LayoutParams layoutParams = new LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, iPx);
lineView.setLayoutParams(layoutParams);
lineView.setBackgroundColor(view.getSolidColor());
LinearLayout ly = new LinearLayout(view.getContext());
ly.setOrientation(LinearLayout.VERTICAL);
ly.addView(view);
ly.addView(lineView);
return ly;
}
/**
* 設置點擊子項事件監聽對象
* @param onItemClickListener
*/
public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
this.onItemClickListener = onItemClickListener;
setItemClickListener();
}
/**
* 獲取點擊子項事件監聽對象
* @return
*/
public OnItemClickListener getOnItemClickListener()
{
return onItemClickListen
『貳』 android 如何讓自定VIEW的顯示超出view的定義大小
在onTouchEvent裡面能獲得當前點擊位置的坐標,根據位置的變化,以原點為基礎,通過scrollBy來設置view的顯示位置。
自定義Layout實現放入其中的組件可以動態改變位置和大小。
自定義CustomLayout.java
package com.wxq.layout;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
//import android.widget.AbsoluteLayout;
public class CustomLayout extends ViewGroup {
public CustomLayout(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CustomLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public CustomLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
3.其中只有自己的布局,其他的View要自己手動添加。
主程序:
TextView mTextView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = getLayoutInflater();
LinearLayout linearLayout = (LinearLayout) inflater.inflate(R.layout.main, null);
mTextView = new TextView(this);
mTextView.setText("wxq say hello!");
mTextView.setTextColor(Color.WHITE);
mTextView.setBackgroundColor(Color.RED);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(100, 100);
CustomLayout cLayout = (CustomLayout) linearLayout.findViewById(R.id.cLayout);
cLayout.setBackgroundColor(Color.BLUE);
cLayout.addView(mTextView,layoutParams);
mTextView.layout(20, 20, 150+20, 150+20);
Log.d("wxq", "mTextView = " +mTextView + ",and parent is:"+mTextView.getParent());
mTextView.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Log.d("wxq", "textW = "+mTextView.getMeasuredWidth()+ ",H = "+mTextView.getMeasuredHeight());
}
});
setContentView(linearLayout);
}
實現的效果如下:
『叄』 從源碼中淺析Android中怎麼利用attrs和styles定義控制項
1.attrs.xml:
我們知道Android的源碼中有attrs.xml這個文件,這個文件實際上定義了所有的控制項的屬性,就是我們在布局文件中設置的各類屬性
你可以找到attrs.xml這個文件,打開它,全選,右鍵->Show In->OutLine。可以看到整個文件的解構
我們大概可以看出裡面是Android中的各種屬性的聲明,比如textStyle這個屬性是這樣定義的:
Java代碼
<!-- Default text typeface style. -->
<attr name="textStyle">
<flag name="normal" value="0" />
<flag name="bold" value="1" />
<flag name="italic" value="2" />
</attr>
那麼現在你知道,我們在寫android:textStyle的時候為什麼會出現normal,bold和italic這3個東西了吧,就是定義在這個地方。
再看看textColor:
Java代碼
<!-- Color of text (usually same as colorForeground). -->
<attr name="textColor" format="reference|color" />
format的意思是說:這個textColor可以以兩種方式設置,要麼是關聯一個值,要麼是直接設置一個顏色的RGB值,這個不難理解,因為我們可以平時也這樣做過。
也就是說我們平時在布局文件中所使用的各類控制項的屬性都定義在這裡面,那麼這個文件,除了定義這些屬性外還定義了各種具體的組件,比如TextView,Button,SeekBar等所具有的各種特有的屬性
比如SeekBar:
Java代碼
<declare-styleable name="SeekBar">
<!-- Draws the thumb on a seekbar. -->
<attr name="thumb" format="reference" />
<!-- An offset for the thumb that allows it to extend out of the range of the track. -->
<attr name="thumbOffset" format="dimension" />
</declare-styleable>
也許你會問SeekBar的background,等屬性怎麼沒有看到?這是因為Android中幾乎所有的組件都是從View中繼承下來的,SeekBar自然也不例外,而background這個屬性幾乎每個控制項都有,因此被定義到了View中,你可以在declare-styleable:View中找到它。
總結下,也就是說attrs.xml這個文件定義了布局文件中的各種屬性attr:***,以及每種控制項特有的屬性declare-styleable:***
2.styles.xml:
剛才的attrs.xml定義的是組件的屬性,現在要說的style則是針對這些屬性所設置的值,一些默認的值。
這個是SeekBar的樣式,我們可以看到,這裡面設置了一個SeekBar的默認的樣式,即為attrs.xml文件中的各種屬性設置初始值
Java代碼
<style name="Widget.SeekBar">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
<item name="android:indeterminateDrawable">@android:drawable/progress_horizontal</item>
<item name="android:minHeight">20dip</item>
<item name="android:maxHeight">20dip</item>
<item name="android:thumb">@android:drawable/seek_thumb</item>
<item name="android:thumbOffset">8dip</item>
<item name="android:focusable">true</item>
</style>
這個是Button的樣式:
Java代碼
<style name="Widget.Button">
<item name="android:background">@android:drawable/btn_default</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>
<item name="android:textColor">@android:color/primary_text_light</item>
<item name="android:gravity">center_vertical|center_horizontal</item>
</style>
有了屬性和值,但是這些東西是如何關聯到一起的呢?它們如何被android的framework層所識別呢?
3.組件的源碼
我們看下TextView的源碼:
Java代碼
public TextView(Context context) {
this(context, null);
}//這個構造器用來給用戶調用,比如new TextView(this);
public TextView(Context context,
AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.textViewStyle);
}
public TextView(Context context,
AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);//為用戶自定義的TextView設置默認的style
mText = "";
//設置畫筆
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.density = getResources().getDisplayMetrics().density;
mTextPaint.setCompatibilityScaling(
getResources().getCompatibilityInfo().applicationScale);
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mHighlightPaint.setCompatibilityScaling(
getResources().getCompatibilityInfo().applicationScale);
mMovement = getDefaultMovementMethod();
mTransformation = null;
//attrs中包含了這個TextView控制項在布局文件中定義的屬性,比如android:background,android:layout_width等
//com.android.internal.R.styleable.TextView中包含了TextView中的針對attrs中的屬性的默認的值
//也就是說這個地方能夠將布局文件中設置的屬性獲取出來,保存到一個TypeArray中,為這個控制項初始化各個屬性
TypedArray a =
context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
int textColorHighlight = 0;
ColorStateList textColor = null;
ColorStateList textColorHint = null;
ColorStateList textColorLink = null;
int textSize = 15;
int typefaceIndex = -1;
int styleIndex = -1;
/*
* Look the appearance up without checking first if it exists because
* almost every TextView has one and it greatly simplifies the logic
* to be able to parse the appearance first and then let specific tags
* for this View override it.
*/
TypedArray appearance = null;
//TextView_textAppearance不太了解為什麼要這樣做?難道是為了設置TextView的一些默認的屬性?
int ap = a.getResourceId(com.android.internal.R.styleable.TextView_textAppearance, -1);
if (ap != -1) {
appearance = context.obtainStyledAttributes(ap,
com.android.internal.R.styleable.
TextAppearance);
}
if (appearance != null) {
int n = appearance.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = appearance.getIndex(i);
switch (attr) {
case com.android.internal.R.styleable.TextAppearance_textColorHighlight:
textColorHighlight = appearance.getColor(attr, textColorHighlight);
break;
case com.android.internal.R.styleable.TextAppearance_textColor:
textColor = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textColorHint:
textColorHint = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textColorLink:
textColorLink = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textSize:
textSize = appearance.getDimensionPixelSize(attr, textSize);
break;
case com.android.internal.R.styleable.TextAppearance_typeface:
typefaceIndex = appearance.getInt(attr, -1);
break;
case com.android.internal.R.styleable.TextAppearance_textStyle:
styleIndex = appearance.getInt(attr, -1);
break;
}
}
appearance.recycle();
}
//各類屬性
boolean editable = getDefaultEditable();
CharSequence inputMethod = null;
int numeric = 0;
CharSequence digits = null;
boolean phone = false;
boolean autotext = false;
int autocap = -1;
int buffertype = 0;
boolean selectallonfocus = false;
Drawable drawableLeft = null, drawableTop = null, drawableRight = null,
drawableBottom = null;
int drawablePadding = 0;
int ellipsize = -1;
boolean singleLine = false;
int maxlength = -1;
CharSequence text = "";
CharSequence hint = null;
int shadowcolor = 0;
float dx = 0, dy = 0, r = 0;
boolean password = false;
int inputType = EditorInfo.TYPE_NULL;
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
//通過switch語句將用戶設置的,以及默認的屬性讀取出來並初始化
switch (attr) {
case com.android.internal.R.styleable.TextView_editable:
editable = a.getBoolean(attr, editable);
break;
case com.android.internal.R.styleable.TextView_inputMethod:
inputMethod = a.getText(attr);
break;
case com.android.internal.R.styleable.TextView_numeric:
numeric = a.getInt(attr, numeric);
break;
//更多的case語句...
case com.android.internal.R.styleable.TextView_textSize:
textSize = a.getDimensionPixelSize(attr, textSize);//設置當前用戶所設置的字體大小
break;
case com.android.internal.R.styleable.TextView_typeface:
typefaceIndex = a.getInt(attr, typefaceIndex);
break;
//更多的case語句...
}
通過上面的代碼大概可以知道,每個組件基本都有3個構造器,其中只傳遞一個Context上下文的那個構造器一般用來在java代碼中實例化使用。
比如你可以
Java代碼
TextView tv = new TextView(context);
來實例化一個組件。
最終調用的是第3個構造器
Java代碼
public TextView(Context context,
AttributeSet attrs,
int defStyle)
在這個構造器中為你設置了默認的屬性attrs和值styles。關鍵不在這里,而是後面通過使用下面的代碼
Java代碼
TypedArray a =
context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
來將屬性和值獲取出來,放到一個TypeArray中,然後再利用一個switch語句將裡面的值取出來。再利用這些值來初始化各個屬性。這個View最終利用這些屬性將這個控制項繪制出來。
如果你在布局文件中定義的一個View的話,那麼你定義的值,會被傳遞給構造器中的attrs和styles。也是利用同樣的方式來獲取出你定義的值,並根據你定義的值來繪制你想要的控制項。
再比如其實Button和EditText都是繼承自TextView。看上去兩個控制項似乎差異很大,其實不然。Button的源碼其實相比TextView變化的只是style而已:
『肆』 android中常用的資源有哪些
Android 資源類型
1.字元串資源
>>1.普通字元串
>>2.字元串數組
復制代碼
<resources>
<string-array name="planets_array">
<item>aaa</item>
<item>bbb</item>
</string-array>
</resources>
復制代碼
獲取方式:getResources().getStringArray(R.array.planets_array)
>>3.復數字元串資源
某些自然語言中,不同的數字在使用方法上會有所不同,比如one book,two books。當數量大於1時,會使用不同的名詞或其它復數形式;
復制代碼
<resources>
<plurals name="numberOfp">
<item quantity="one">one person</item>
<item quantity="other">more persons</item>
</plurals>
</resources>
復制代碼
quantity屬性的值除了one和other外,還可以是zero,two,few,many;
引用復數字元串:
// 引用數字為1的復數字元串
getResources().getQuantityString(R.pluarlas.numberOfp,1);
// 引用數字為其它值的復數字元串
getResources().getQuantityString(R.pluarlas.numberOfp,10,10);
>>4.佔位符格式化字元串
常用的格式化字元串三種方法:
>>1.在字元串中使用引號
字元串中的值雖然可以隨意指定,但是當遇到特殊符號時(雙引號,單引號)就需要採取特殊的方法來處理這些符號。
如果是單引號(')可以使用轉義符(\)或用雙引號(")將整個字元串括起來,如果是雙引號,可以在雙引號前使用轉義符(\)。
<resources>
<string name="str1">"This'll work"</string> This'll work
<string name="str2">This\'ll work</string> This'll work
<string name="str3">\"apple\"</string> "apple"
</resources>
>>2.用佔位符格式化字元串
使用String.format(String,Object...)方法可以格式化帶佔位符的字元串,只需要在字元串中插入佔位符,就可以使用String.format方法格式化字元串資源,format方法要求的佔位符用%1,%,...,%n,其實第n個佔位符與format方法的n+1個參數值對應;
<resources>
<!-- $s表示該佔位符被字元串替換,$d表示該佔位符被整數替換 -->
<string name="str1">hello,%1$s!You have %2$d new message</string>
</resources>
String str1 =String.format(getResources().getString(R.string.str1), "ly", 17);
>>3.使用HTML標簽格式化字元串資源
字元串資源支持一些HTML標簽,因此可以直接在字元串資源中使用這些HTML標簽格式化字元串
字元串資源支持如下的HTML標簽
<b>粗體字
<i>斜體定
<u>帶下劃線的字
有時需要同時使用HTML標簽和佔位符格式化字元串,如果使用String.format方法格式化字元串,會忽略字元串中的所有HTML標簽。為了使format方法可以格式化帶
HTML標簽的確字元,需要使用Html.formHTML方法處理字元串;
<resources>
<string name="hello_world">Welcome to <b>android</b></string>
<string name="str2">Hello,%1$s! You have <b> %2d new messages </b></string> <!--同時包含佔位符和html標簽的字元串-->
</resources>
由於需要使用Html.formHTML方法處理字元串,因此HTML標簽中的 "<" 需要使用 "<" 表示 ">" 並不需要處理
獲取字元串:
String text = String.format(getResources().getString(R.string.str2), "ly", 10);
CharSequence styledText = Html.fromHtml(text);
// 如果format的某個參數包含HTML的特殊字元,如"<","&",可以使用如下方式讀取字元串的值;
String escapedUsername = TextUtils.htmlEncode("");
String text1 = String.format(getResources().getString(R.string.str2), "ly", 20);
2.Layout資源
1、如果根節點是View,除了<requestFocus>標簽外,不能添加任何子標簽,<requestFocus>可能被添加到布局文件的任何View中,表示該標簽對應的控制項在顯示時處於焦點狀態,整個布局文件只能有一個<requestFocus>標簽
2、根節點是ViewGroup,常用的布局都是ViewGroup的子類
3、重用布局文件
如果想重用某個布局文件,可以使用<include>標簽
<include layout="@layout/xx_layout" />
如果想讓一個布局文件被另一個布局文件引用(使用<include>標簽),可以使用<merge>作為被引用布局文件的根節點,由於<merge>並不會生成任何標簽(在大量引用布局文件時不至於生成大量無用的標簽),但是xml文件必須要有一個根節點,因此<merge>所起的作用就是作為xml文件的根節點,以使xml文件在編譯時不至於出錯,可以把<merge>當成<FrameLayout>使用;
3.圖像資源
在圖像資源中可以存儲圖像文件,還可以使用xml格式的圖像資源來控制項圖像的狀態和行為;
>>1.普通圖像資源
Drawable da = getResources().getDrawable(R.drawable.xxx);
>>2.xml圖像資源
xml圖像資源其實就是在drawable目錄中指定的xml文件,此種方式可以額外指定圖像的某些屬性,如圖像拉動、排列方式;
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher"
android:tileMode="repeat" >
</bitmap>
>>3.Nine-Patch圖像資源
Nine-Patch圖像資源文件必須以9.png作為文件擴展名,如abc.9.png
該圖像資源的主要作用是:防止圖像的某一部分被拉伸;確定將圖像作為背景圖的控制項中內容顯示的位置;
Android SDK本身提供了一個Draw 9-patch的工具,啟動<sdk目錄>\tools\draw9patch.bat命令啟動該工具;
可以通過此工具在png圖的四周繪制1個像素粗的直線,上邊緣和左邊緣的直線分別表示圖像在水平和垂直方向可位值的范圍。如果水平或垂直方向的某個區域不需要拉伸,則可不繪制相應的直線;右邊緣和下邊緣的直線分別表示圖像所在控制項中內容的顯示範圍,內容只在右邊緣和下邊緣繪制直線的區域顯示,表示內容顯示範圍和拉伸范圍的兩給直線有一個重要區別就是表示內容顯示範圍的直線中間不能斷開,而表示拉伸范圍的直線中間可以斷開;
Nine-Patch圖像資源與普通圖像資源引用方法相同,在引用時只寫文件名,活力.9.png;
>>4.XML Nine-Patch圖像資源
Nine-Patch圖像資源也有與其對應的xml圖像資源,使用<nine-patch>標簽來引用Nine-Patch格式的圖像,有一個設置抖動的android:dither屬性;
>>5.圖層資源
圖層資源類似於<FrameLayout>不同的是<FrameLayout>標簽中可以包含任意的控制項,而圖層資源每一層都只有是圖像,定義圖層資源必須使用<layer-list>作為資源文件的根節點,<layer-list>標簽中包含多個<item>標簽,每一個標簽表示一個圖像,最後一個<item>標簽顯示在最頂層;
默認情況下,圖像會盡量充滿顯示圖像的范圍,圖像可能會有拉伸,為了避免圖像拉伸,可以在<item>標簽中使用<bitmap>標簽引用圖像;
復制代碼
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:bottom="10dip" 底端偏移的像素
android:left="10dip" 左側偏移的像素
android:right="10dip" ...
android:top="10dip"> ...
<bitmap
android:gravity="center"
android:src="@drawable/hell" />
</item>
</layer-list>
復制代碼
某些情況下,可以使用圖層來代替<FrameLayout>
>>6.圖像狀態資源,處理控制項不同狀態下的顯示狀態
復制代碼
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bm" android:state_focused="true"></item>
<item android:drawable="@drawable/bm" android:state_pressed="true"></item>
<item android:drawable="@drawable/bm"></item>
</selector>
// android:state_focused/pressed設置為true表示當前item的drawable屬性為獲取焦點和按下時的drawable樣式
復制代碼
>>7.圖像級別(Level)資源
圖像資源狀態只能指定幾種有限的狀態,可以通過圖像級別指定更多的狀態;圖像級別是一個整數的區間,可以通過ImageView.setImageLevel或Drawable.setLevel方法切換不同狀態的圖像;圖像級別資源是xml文件,必須以<level-list>為根節點,每一個item表示一個級別區間,下面是一個xml文件;通過ImageView.setImageLevel(level),根據level所在的區間設定顯示的圖像資源,如果level不在任一區間內則清空ImageView當前圖像;
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="2" android:minLevel="0" android:drawable="@drawable/hell" />
<item android:maxLevel="4" android:minLevel="3" android:drawable="@drawable/hell" />
</level-list>
>>8.淡入淡出(Cross-fade)資源
也是切換兩個圖像(不支持多於兩個圖像的切換),並且使這兩個圖像以淡入淡出效果進行切換,如電燈在開關時逐漸變亮或逐漸變暗;
<transition xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/hell"/>
<item android:drawable="@drawable/hell"/>
</transition>
TransitionDrawable da = ...;
// 從第一張圖片切換到第二張圖片,時間效果為1秒
da.startTransition(1000);
// 從第二張圖片切換到第一張圖片,時間效果為1秒
da.reverseTransition(1000);
>>9.嵌入(insert)圖像資源
使用場景:要顯示的圖像要求要小於裝載圖像的View(圖小於View區域),也是通過xml資源定義,只有一個節點inset。
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/hell"
android:insetLeft="10dip" > <!--圖像距離左邊的距離,延伸-->上/下/右的距離-->
</inset>
>>10.剪切(Clip)圖像資源,使用剪切圖像資源可以只顯示圖像的一部分,如可以通過此來製作進度條;
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="horizontal" // 指定截取的方向
android:drawable="@drawable/hell" // 指定要截取的圖像
android:gravity="left" > // 指定截取的方式,在此為從左側開始截取
</clip>
ClipDrawable cd = ...;
cd.setLevel(1000);
上面ClipDrawable.setLevel(level)設置截取的圖像寬度,ClipDrawable預設了最大值10000(表示不進行截取),最小值為0(表示不顯示);
>>11. 比例(Scale)圖像資源
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/hell"
android:scaleGravity="center" // 設置圖像顯示的位置
android:scaleHeight="70%" // 設置圖像顯示的高度
android:scaleWidth="80%" > // 設置圖像顯示的寬度
</scale>
>>12.形狀資源
復制代碼
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" > shape可以指定就矩形,oval(橢圓),line(直線),ring(圓)
<corners> 定義圓角
</corners>
<gradient
android:angle="45"
android:startColor="#000000"
android:endColor="#FFFFFF" > 定義顏色漸變,從左下角到或上角
</gradient>
<padding> 定義控制項內容到邊框的距離
</padding>
<stroke> 定義邊線
</stroke>
<solid> 定義填充
</solid>
<size> 定義大小
</size>
</shape>
復制代碼
13.菜單資源
菜單不僅可以在onCreateContextMenu或onCreateOptionsMenu方法中通過代碼創建,還可以在res/menu目錄中建立相應的菜單資源文件,並在上面兩個方法中載入菜單資源;
菜單資源文件必須以<menu>標簽作為根節點,每一個菜單項用一個<item>表示,如果要定義子菜單,可以在<item>標簽中包含<menu>標簽;如果想將多個菜單項劃為一組,可以使用<group>包含多個<item>標簽;
復制代碼
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
復制代碼
查看MenuInflater.inflate(int,Menu)
復制代碼
/**
* Inflate a menu hierarchy from the specified XML resource.
*
* @param menuRes Resource ID for an XML layout resource to load (e.g., <code>R.menu.main_activity</code>)
* @param menu The Menu to inflate into. The items and submenus will be added to this Menu.
*/
public void inflate(int menuRes, Menu menu) {
XmlResourceParser parser = null;
try {
parser = mContext.getResources().getLayout(menuRes);
AttributeSet attrs = Xml.asAttributeSet(parser);
parseMenu(parser, attrs, menu);
} catch ...finally {
if (parser != null) parser.close();
}
}
復制代碼
14.樣式與主題(style/theme)
>>1.樣式style
android中樣式和css中樣式作用是一樣的,都是用於為界面元素定義顯示風格,它是一個包含一個或者多個控制項屬性的集合。
定義樣式需要在res/values/styles.xml中進行定義,如下是一個樣式的定義:
<style name="textViewStyle">
<item name="android:textSize">22sp</item>
<item name="android:textColor">#FF0000</item>
</style>
<style name="textViewStyle1" parent="textViewStyle"></style><!-- 此樣式繼承自textViewStyle -->
<style name="textViewStyle.Livingstone"><!-- 樣式繼承的另一種寫法,但不可用此寫法繼承Android自帶的定義樣式? -->
<item name="android:textColor">#00FF00</item>
</style>
所有定義的樣式都會在R文件中自動生成一個資源ID,加一個點表示樣式繼承會生成上圖所示的資源id;
樣式的引用:
<TextView
style="@style/textViewStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="hello" />
>>2.主題Theme
主題應用於整個應用或者activity,樣式應用於具體的控制項上。主題的應用與樣式定義一樣,不同的是主題還可以設置窗口的顯示風格;主題的引用需要在清單文件中進行引用,如引用到整個應用之上就需要在Application節點中進行配置引用,而引用到單個Activity只需要在此Activity中進行配置引用;
復制代碼
<style name="Livingstonetheme"><!--此定義是一個無Title的主題-->
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">?android:windowNoTitle</item>
<!-- 問號表示引用此主題中android:windowNoTitle屬性的值 -->
<item name="android:textSize">18sp</item>
</style>
復制代碼
android系統定義了一些屬性,如android:theme="@android:style/Theme.Dialog",該主題可以讓Activity看起來像一個對話框,更多主題可以在文檔reference->android->R.style中查看。當主題裡面的樣式屬性值與樣式裡面的屬性值發生沖突的時候會顯示樣式裡面的值;
15.其它資源
在資源文件中還可以包括尺寸(dimen)、整數(integer)、布爾(bool) 、整形數組資源(integer-array)、資源數組(array)、顏色(color)
TypedArray ta = getResources().obtainTypedArray(int id); // 獲取數組資源,包括integer-array、array
Final總結:
除了res/values目錄中的資源名,其它目錄的資源都會以文件名在R類的相應子類中生成變數;而res/values中的資源會以name屬性值為變數名在R類的相應子類中生成變數;
『伍』 android 自定義控制項 屬性怎麼用
自定義屬性設置
public class lei extends RelativeLayout {
private TextView tv1
public lei(Context context) {
super(context);
}
public lei(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.item,this);
tv1 = findViewById(R.id.tv1);
TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.lei);
String str1 = (String) array.getText(R.styleable.lei_settitle);
int str2 = array.getColor(R.styleable.lei_setbackgroudcolor,Color.BLACK);
tv1.setText(str1);
tv1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), "toast", Toast.LENGTH_SHORT).show();
}
});
array.recycle();
}
}
布局控制項
<com.example.administrator.myapplication.lei
android:id="@+id/ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
cs:setbackgroudcolor="#158616"
cs:settitle="這個是標題"
cs:settitletextcolor="#FFFFFF"
cs:settextrcolor="#FFFFFF"
>
</com.example.administrator.myapplication.lei>
屬性設置
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="lei" >
<attr name="setbackgroudcolor" format="color|reference"/>
<attr name="settitle" format="string|reference"/>
<attr name="settextrcolor" format="color"/>
<attr name="settitletextcolor" format="color"/>
</declare-styleable>
</resources>
『陸』 android 左右滑屏怎麼實現 哪位大神教教我
代碼如下:
package kexc.scroll;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;
/**
* 仿Launcher中的WorkSapce,可以左右滑動切換屏幕的類
*
*/
public class ScrollLayout extends ViewGroup {
/*
* onMeasure方法在控制項的父元素正要放置它的子控制項時調用。它會問一個問題,「你想要用多大地方啊?」,然後傳入兩個參數——
* widthMeasureSpec和heightMeasureSpec。它們指明控制項可獲得的空間以及關於這個空間描述的元數據。
* 比返回一個結果要好的方法是你傳遞View的高度和寬度到setMeasuredDimension方法里。
* 一個MeasureSpec包含一個尺寸和模式。
* 有三種可能的模式:
* UNSPECIFIED:父布局沒有給子布局任何限制,子布局可以任意大小。
* EXACTLY:父布局決定子布局的確切大小。不論子布局多大,它都必須限制在這個界限里。
* AT_MOST:子布局可以根據自己的大小選擇任意大小。
*/
/*
* VelocityTracker類
*
* 功能: 根據觸摸位置計算每像素的移動速率。
*
* 常用方法有:
*
* public void addMovement (MotionEvent ev) 功能:添加觸摸對象MotionEvent , 用於計算觸摸速率。
* public void computeCurrentVelocity (int units)
* 功能:以每像素units單位考核移動速率。額,其實我也不太懂,賦予值1000即可。 參照源碼 該units的意思如下: 參數 units :
* The units you would like the velocity in. A value of 1 provides pixels
* per millisecond, 1000 provides pixels per second, etc. public float
* getXVelocity () 功能:獲得X軸方向的移動速率。
*/
/*
* ViewConfiguration類
*
* 功能: 獲得一些關於timeouts(時間)、sizes(大小)、distances(距離)的標准常量值 。
*
* 常用方法:
*
* public int getScaledEdgeSlop()
*
* 說明:獲得一個觸摸移動的最小像素值。也就是說,只有超過了這個值,才代表我們該滑屏處理了。
*
* public static int getLongPressTimeout()
*
* 說明:獲得一個執行長按事件監聽(onLongClickListener)的值。也就是說,對某個View按下觸摸時,只有超過了
*
* 這個時間值在,才表示我們該對該View回調長按事件了;否則,小於這個時間點松開手指,只執行onClick監聽
*/
private static final String TAG = "ScrollLayout";
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private int mCurScreen;//當前屏幕
private int mDefaultScreen = 0;
//兩種狀態: 是否處於滑屏狀態
private static final int TOUCH_STATE_REST = 0;//靜止狀態
private static final int TOUCH_STATE_SCROLLING = 1;//滑屏狀態
private static final int SNAP_VELOCITY = 600; //最小的滑動速率
private int mTouchState = TOUCH_STATE_REST;
private int mTouchSlop;// change 多少像素算是發生move操作
private float mLastMotionX;
private float mLastMotionY;
public ScrollLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
// TODO Auto-generated constructor stub
}
public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
mScroller = new Scroller(context);
mCurScreen = mDefaultScreen;
//初始化一個最小滑動距離
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
/**
* 生成view
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
if (changed) {
int childLeft = 0;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View childView = getChildAt(i);
if (childView.getVisibility() != View.GONE) {
final int childWidth = childView.getMeasuredWidth();
childView.layout(childLeft, 0, childLeft + childWidth,
childView.getMeasuredHeight());
childLeft += childWidth;
}
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.e(TAG, "onMeasure");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(
"ScrollLayout only canmCurScreen run at EXACTLY mode!");
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(
"ScrollLayout only can run at EXACTLY mode!");
}
// The children are given the same width and height as the scrollLayout
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
// Log.e(TAG, "moving to screen "+mCurScreen);
scrollTo(mCurScreen * width, 0);
}
/**
* According to the position of current layout scroll to the destination
* page.
*/
public void snapToDestination() {
// 判斷是否超過下一屏的中間位置,如果達到就抵達下一屏,否則保持在原屏幕
// 這樣的一個簡單公式意思是:假設當前滑屏偏移值即 scrollCurX 加上每個屏幕一半的寬度,除以每個屏幕的寬度就是
// 我們目標屏所在位置了。 假如每個屏幕寬度為320dip, 我們滑到了500dip處,很顯然我們應該到達第二屏,索引值為1
// 即(500 + 320/2)/320 = 1
final int screenWidth = getWidth();
final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth;
snapToScreen(destScreen);
}
public void snapToScreen(int whichScreen) {
// get the valid layout page
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
if (getScrollX() != (whichScreen * getWidth())) {
final int delta = whichScreen * getWidth() - getScrollX();
mScroller.startScroll(getScrollX(), 0, delta, 0,
Math.abs(delta) * 5);
mCurScreen = whichScreen;
onScreenChangeListener.onScreenChange(mCurScreen);
invalidate(); // Redraw the layout
}
}
public void setToScreen(int whichScreen) {
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
mCurScreen = whichScreen;
scrollTo(whichScreen * getWidth(), 0);
}
public int getCurScreen() {
return mCurScreen;
}
/**
* 控制view跟隨手指滑動 由父視圖調用用來請求子視圖根據偏移值 mScrollX,mScrollY重新繪制
*/
@Override
public void computeScroll() {
// 如果返回true,表示動畫還沒有結束
// 因為前面startScroll,所以只有在startScroll完成時 才會為false
if (mScroller.computeScrollOffset()) {
// 產生了動畫效果,根據當前值 每次滾動一點
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
/*
* 其中:onInterceptTouchEvent()主要功能是控制觸摸事件的分發,例如是子視圖的點擊事件還是滑動事件。
* 其他所有處理過程均在onTouchEvent()方法里實現了。 1、屏幕的滑動要根據手指的移動而移動 ----
* 主要實現在onTouchEvent()方法中
*