zoukankan      html  css  js  c++  java
  • Android API Guide 之 User Interface笔记

     
    一、Layouts

    在XML中,标签名对应于代码中的类名,属性名对应于代码中的方法名

    2 android:id="@+id/start"
    @ 让XML解析器知道后面的字符串应该解析为一个 Resource ID
    + 表明是自己定义的新的ID,不是系统built-in的,
    如果使用系统的应该是这样android:id="@android:id/empty"

    3 ViewGroup.LayoutParams
    这是一个类,只不过是一个内部静态类,不过在这里把它当做一个类即可.
    一个View应该具有一个ViewGroup.LayoutParams对象,并对这个对象进行
    适当的初始化,这样它的parent才能知道如何放置它.
    想一想当我们在XML中定义一个按钮时它总是具有一个 layout_width/layout_height属性,
    这就相当于
    ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(layout_width,layout_height);
    View.setLayoutParams(layoutParams);

    View.getLeft()/View.getTop()
    The size of a view is expressed with a width and a height. 
    A view actually possess two pairs of width and height values. 
    measured width/height --> getMeasuredWidth/Height() //在parent内一个View有多大
    width/height --> getWidth/Height() //一个View真正的尺寸
    View可以有padding --> setPadding(int,int,int,int) getPaddingLeft/Top/Right/Bottom()
    View可以有margin,但是是通过 ViewGroup.MarginLayoutParams 来设置的.

    4
    注意像 ListView/GridView 都是ViewGroup

    5 如果设置一个View的background
    android:background     setBackgroundResource(int)     A drawable to use as the background.
    对于按钮又可以在 /res/drawable 目录下定义如下xml文件:

    custom_background.xml (把此文件当做一个 drawable 来用)

    [html] view plaincopy
    1. <!-- 具体定义此文件的语法可以在 Resource Type 相关的API Guide中找到 -->  
    2. <?xml version="1.0" encoding="utf-8"?>  
    3. <selector xmlns:android="http://schemas.android.com/apk/res/android">  
    4.     <item android:drawable="@drawable/button_pressed"  
    5.           android:state_pressed="true" />  
    6.     <item android:drawable="@drawable/button_focused"  
    7.           android:state_focused="true" />  
    8.     <item android:drawable="@drawable/button_default" />  
    9. </selector>  
    6 EditView 常用设置
    android:inputType 用来指定是数字,email,password等输入类型
    android:textmultiLine 指定EditView可以有多行
    android:imeOptions 指定一个按钮在EditView的末尾,以便用户输入完成后点击

    7
    AutoCompleteTextView 需要设置一个 Adapter

    8 Input Events
    View类内部定义的事件接口有:(注意有些方法返回的是boolean型,搞明白为什么)
    View.OnClickListener --> public void onClick(View v)
    View.OnLongClickListener --> boolean onLongClick (View v)
    View.OnFocusChangeListener --> void onFocusChange (View v, boolean hasFocus)
    View.OnKeyListener --> boolean onKey (View v, int keyCode, KeyEvent event)
    View.OnTouchListener -->  boolean onTouch (View v, MotionEvent event)
    //这个事件是在onLongClick的情况下发生的
    View.OnCreateContextMenuListener 
    -->void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)

    9 Touch Mode
    For a touch-capable device, once the user touches the screen, 
    the device will enter touch mode.

    Any time a user hits a directional key or scrolls with a trackball, the device will exit
    touch mode, and find a view to take focus.

    10 Focus
    Focus movement 有一个普遍的算法,即会把焦点移动到离现在View最近的那个View;但有时这种算法
    并不适合开发者,开发者可以通过以下方法声明焦点转移的顺序.

    [html] view plaincopy
    1. <LinearLayout android:orientation="vertical"  
    2.     ... >  
    3.   <Button android:id="@+id/top"  
    4.           android:nextFocusUp="@+id/bottom"  
    5.           ... />  
    6.   <Button android:id="@+id/bottom"  
    7.           android:nextFocusDown="@+id/top"  
    8.           ... />  
    9. </LinearLayout>  
    共四种:nextFocusDown, nextFocusLeft, nextFocusRight, and nextFocusUp
    和焦点相关的属性还有:
    android:focusable
    android:focusableInTouchMode

    requestFocus()

    二、Menus
    三种菜单: 
    Options menu(用Menu按键触发,android3.0已经取消这个按键,用action bar代替)
    Context menu
    Popup menu

    1 定义一个Menu in XML
    game_menu.xml:

    [html] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <menu xmlns:android="http://schemas.android.com/apk/res/android">  
    3.     <item android:id="@+id/new_game"  
    4.           android:icon="@drawable/ic_new_game"  
    5.           android:title="@string/new_game"  
    6.           <!-- 此属性和action bar相关 -->  
    7.           android:showAsAction="ifRoom">  
    8.           <!-- item里可以嵌套menu -->  
    9.           <menu>  
    10.             ...  
    11.           </menu>  
    12.     </item>  
    13.     <item android:id="@+id/help"  
    14.           android:icon="@drawable/ic_help"  
    15.           android:title="@string/help" />  
    16. </menu>  
    用 MenuInflater.inflate() 去解析XML菜单;

    2 制定Option menu
    覆盖Activity. onCreateOptionsMenu() 去生成自己的菜单,此方法只在第一次生成options menu时
    被调用,对于以后菜单的更改可以在 onPrepareOptionsMenu(Menu) 中完成.

    当点击option menuitem 时会触发 onOptionsItemSelected()

    3 制定Context menu(具体请参考API Guid)
    registerForContextMenu() and pass it the View;
    Implement the onCreateContextMenu() method in your Activity;
    Implement onContextItemSelected().

    4 制定 Popup Menu(API11 才有)

    5 Create Menu Group(看API Guide)

    6 Using checkable menu

    [html] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <menu xmlns:android="http://schemas.android.com/apk/res/android">  
    3.     <group android:checkableBehavior="single">  
    4.         <item android:id="@+id/red"  
    5.               android:title="@string/red" />  
    6.         <item android:id="@+id/blue"  
    7.               android:title="@string/blue" />  
    8.     </group>  
    9. </menu>  
    single
        Only one item from the group can be checked (radio buttons)
    all
        All items can be checked (checkboxes)
    none
        No items are checkable 
    另外当某个菜单项被按下时你必须自己改变其check状态,系统不会自动改变,就像:

    [java] view plaincopy
    1. @Override  
    2. public boolean onOptionsItemSelected(MenuItem item) {  
    3.     switch (item.getItemId()) {  
    4.         case R.id.vibrate:  
    5.         case R.id.dont_vibrate:  
    6.             //改变这些menu item的状态  
    7.             if (item.isChecked()) item.setChecked(false);  
    8.             else item.setChecked(true);  
    9.             return true;  
    10.         default:  
    11.             return super.onOptionsItemSelected(item);  
    12.     }  
    13. }  
    三、Dialogs
                   <-- AlertDialog
                  <-- ProgressDialog
    Dialog  <-- DatePickerDialog
                  <-- TimePickerDialog

    A dialog is always created and displayed as a part of an Activity.
    一般情况下你会调用 Activity.onCreateDialog(int) 方法创建Dialog,这时Android System会管理
    Dialog的状态并把此Dialog的拥有者设为此Activity.
    Activity.onCreateDialog(int) --> (只在第一次创建Dialog时被调用)
    Activity.onPrepareDialog(int) (显示前设置Dialog属性)--> Activity.showDialog(int) -->
    Activity.dismissDialog(int)/Dialog.dismiss() (Dialog不在显示但Activity会保存其状态) -->
    Activity.removeDialog(int) (Dialog被从Activity中删除,这个Dialog的引用被置null)

    创建Dialog的一般步骤为:

    [java] view plaincopy
    1. //定义好Dialog ID  
    2. static final int DIALOG_PAUSED_ID = 0;  
    3. static final int DIALOG_GAMEOVER_ID = 1;  
    4. //创建时调用  
    5. protected Dialog onCreateDialog(int id) {  
    6.     Dialog dialog;  
    7.     switch(id) {  
    8.     case DIALOG_PAUSED_ID:  
    9.         // do the work to define the pause Dialog  
    10.         break;  
    11.     case DIALOG_GAMEOVER_ID:  
    12.         // do the work to define the game over Dialog  
    13.         break;  
    14.     default:  
    15.         dialog = null;  
    16.     }  
    17.     return dialog;  
    18. }  
    19. //显示Dialog  
    20. showDialog(DIALOG_PAUSED_ID);  
    AlertDialog的创建可以使用其Builder,比较简单,具体可以参考API Guide.

    ProgressDialog 包括两种,一种为进度条长度不能确定的 spinning circle,另一种有进度条长度且可以
    更新这个进度条(此情况下一般会新建一个更新进度条的Thread),这两种情况都不是很复杂,具体请参看
    API Guide.

    定制自己的Dialog,可以继承自 Dialog也可以继承自 AlertDialog(这样可以利用它的按钮的相关特征),

    具体请参看API Guide.

    四、Notifications
    1 Toast Notifications
    A toast can be created and displayed from an Activity or Service.

    2 设置一个 Toast 显示的位置
    toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 0); 或
    toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
    如果想往右一点就设置第2个参数,如果想往下一点就设置第3个参数,具体请参考Toast API

    3 Status Notifications
    一般是由background的service发出,要使用 Notification和NotificationManager


    一个PendingIntent只是代表一个系统内部的 IIntentSender, PendingIntent本身只是一个符号.

    下面是文档中的一个例子,花了一点时间研究了一下,下面做一下注释,以笔记下研究成果.(虽然很小)

    [java] view plaincopy
    1. static Intent[] makeMessageIntentStack(Context context, CharSequence from,  
    2.         CharSequence msg) {  
    3.     Intent[] intents = new Intent[4];  
    4.     //查看 Intent.makeRestartActivityTask说明  
    5.     //指向一个 root activity  
    6.     intents[0] = Intent.makeRestartActivityTask(new ComponentName(context,  
    7.             com.example.android.apis.ApiDemos.class));  
    8.   
    9.     // "App"  
    10.     intents[1] = new Intent(context, com.example.android.apis.ApiDemos.class);  
    11.     intents[1].putExtra("com.example.android.apis.Path""App");  
    12.     // "App/Notification"  
    13.     intents[2] = new Intent(context, com.example.android.apis.ApiDemos.class);  
    14.     intents[2].putExtra("com.example.android.apis.Path""App/Notification");  
    15.   
    16.     // Now the activity to display to the user.  Also fill in the data it  
    17.     // should display.  
    18.     intents[3] = new Intent(context, IncomingMessageView.class);  
    19.     intents[3].putExtra(IncomingMessageView.KEY_FROM, from);  
    20.     intents[3].putExtra(IncomingMessageView.KEY_MESSAGE, msg);  
    21.   
    22.     return intents;  
    23. }  
    24.   
    25. /** 
    26.  * The notification is the icon and associated expanded entry in the 
    27.  * status bar. 
    28.  */  
    29. void showAppNotification() {  
    30.     // look up the notification manager service  
    31.     NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);  
    32.   
    33.     // The details of our fake message  
    34.     CharSequence from = "Joe";  
    35.     CharSequence message;  
    36.     switch ((new Random().nextInt()) % 3) {  
    37.         case 0: message = "r u hungry?  i am starved"break;  
    38.         case 1: message = "im nearby u"break;  
    39.         default: message = "kthx. meet u for dinner. cul8r"break;  
    40.     }  
    41.   
    42.     //这种行为很像 startActivity(Intent[] intents)  
    43.     //intents[0] 表示一个root activity  
    44.     //intents[1] 相当于 intents[0].startActivity()  
    45.     //intents[] 的最后一个Intent所关联的Activity是与用户交互的,用户可以使用BACK键  
    46.     //回到intents[top-1]  
    47.     //顺便学习了 Intent.fillIn() 和 PendingIntent.send() 方法  
    48.     //上面两个方法要查看相关文档  
    49.     PendingIntent contentIntent = PendingIntent.getActivities(this0,  
    50.             makeMessageIntentStack(this, from, message), PendingIntent.FLAG_CANCEL_CURRENT);  
    51.   
    52.     // The ticker text, this uses a formatted string so our message could be localized  
    53.     String tickerText = getString(R.string.imcoming_message_ticker_text, message);  
    54.   
    55.     // construct the Notification object.  
    56.     Notification notif = new Notification(R.drawable.stat_sample, tickerText,  
    57.             System.currentTimeMillis());  
    58.   
    59.     // Set the info for the views that show in the notification panel.  
    60.     notif.setLatestEventInfo(this, from, message, contentIntent);  
    61.   
    62.     // We'll have this notification do the default sound, vibration, and led.  
    63.     // Note that if you want any of these behaviors, you should always have  
    64.     // a preference for the user to turn them off.  
    65.     notif.defaults = Notification.DEFAULT_ALL;  
    66.   
    67.     // Note that we use R.layout.incoming_message_panel as the ID for  
    68.     // the notification.  It could be any integer you want, but we use  
    69.     // the convention of using a resource id for a string related to  
    70.     // the notification.  It will always be a unique number within your  
    71.     // application.  
    72.     nm.notify(R.string.imcoming_message_ticker_text, notif);  
    73. }  

    Notification.FLAG_AUTO_CANCEL 标记,当用记点击时会自己从"通知栏"消失(加红)

    调用setLatestEventInfo() 对已经发出的Notification进行修正,主要是修改其text message

    5 定制自己的 Notification (看完 Sytle和Theme再回来看)

    五、Sytles and Themes
    自己定义一个 style

    [html] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <!-- 注意resources -->  
    3. <resources>  
    4.     <style name="CodeFont" parent="@android:style/TextAppearance.Medium">  
    5.         <item name="android:layout_width">fill_parent</item>  
    6.         <item name="android:layout_height">wrap_content</item>  
    7.         <item name="android:textColor">#00FF00</item>  
    8.         <item name="android:typeface">monospace</item>  
    9.     </style>  
    10. </resources>  
    如何继承自己定义的 style, 当然可以使用 parent 属性,但你也可以这样做:

    [html] view plaincopy
    1. <style name="CodeFont.Red">  
    2.         <item name="android:textColor">#FF0000</item>  
    3. </style>  
    还可以再继承:

    [html] view plaincopy
    1. <style name="CodeFont.Red.Big">  
    2.         <item name="android:textSize">30sp</item>  
    3. </style>  
    你只能以这种形式继承自己定义的stye,不能以这种形式继承系统内建的style.

    如果一个style中的属性,这个View不支持,它只是把它不支持的属性忽略掉.

    注意 View 的XML中可以有一个 style=""@style/MyStyle" 属性,而Activity和Application可以有一个
    android:theme="@style/MyStyle" 属性.

    如果把一个style应用于一个ViewGroup,则仅仅这个ViewGroup应用这个属性,它的孩子不会应用这个属性.

    使用系统自定义的style
    <activity android:theme="@android:style/Theme.Dialog">

    无论style还是theme都是用<style></style>来定义的,所以平台内建的 style和theme 都可以
    在 android.R.style 中找到常量值,如果对这些常量值不太理解可以通过查看 styles.xml/themes.xml
    查看源代码以帮助理解.现在的问题是,系统内建的style会用到一些属性,比如 
    [html] view plaincopy
    1. <style name="Theme">  
    2.     <item name="colorForeground">@android:color/bright_foreground_dark</item>  
    3.     <item name="colorForegroundInverse">@android:color/bright_foreground_dark_inverse</item>  
    4.     <item name="colorBackground">@android:color/background_dark</item>  
    5.     <item name="colorBackgroundCacheHint">?android:attr/colorBackground</item>   
    6. </style>  
    那么我们如何知道会有哪些属性需要定义呢?

    对于普通的View 可以查看其 Reference 得到其 相关于 XML attributes,还有一些属性
    不是针对某一个View的,而是专门用于Theme类的,如android:windowBackground,我们可以在
    R.styleable.Theme中找到(其实这些attr是在attrs.xml中定义的,只不过在Theme大类下)
    另外:
    For a reference of available style attributes that you can use to define a style 
    or theme (e.g., "windowBackground" or "textAppearance"), see R.attr or the respective 
    View class for which you are creating a style.

    6 定制自己的组件
    Fully Customized Components:
    首先要设计好自己View的特性,即有哪些字段,如下面这个LabelView,它有两个字段:

    [java] view plaincopy
    1. public class LabelView extends View {  
    2.     private String mText;  
    3.     private Paint mPaint;  
    4. }  
    然后完成对各字段设置的函数:

    [java] view plaincopy
    1. public class LabelView extends View {  
    2.     //第一步:确定自己View的字段  
    3.     private String mText;  
    4.     private Paint mPaint;  
    5.       
    6.     //第二步:设置自己字段的方法  
    7.     public void setText(String text) {  
    8.         mText = text;  
    9.     }  
    10.     public void setTextColor(int color) {  
    11.         mPaint.setColor(color);  
    12.     }  
    13.     public void setTextSize(int size) {  
    14.         mPaint.setTextSize(size);  
    15.     }  
    16. }  
    再完成构造函数:

    [java] view plaincopy
    1. public class LabelView extends View {  
    2.     //第一步:确定自己View的字段  
    3.     private String mText;  
    4.     private Paint mPaint;  
    5.       
    6.     //第二步:设置自己字段的方法  
    7.     public void setText(String text) {  
    8.         mText = text;  
    9.     }  
    10.     public void setTextColor(int color) {  
    11.         mPaint.setColor(color);  
    12.     }  
    13.     public void setTextSize(int size) {  
    14.         mPaint.setTextSize(size);  
    15.     }  
    16.       
    17.     //第三步:完成构造函数  
    18.     public LabelView(Context context) {  
    19.         super(context);  
    20.         ...  
    21.     }  
    22.     public LabelView(Context context, AttributeSet attrs) {  
    23.         super(context, attrs);  
    24.         ...  
    25.     }  
    26.       
    27.     //第四步:完成onMearsure()方法  
    28.     @Override  
    29.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    30.         setMeasuredDimension(intint);  
    31.     }  
    32.       
    33.     //第五步:完成onDraw(Canvas)  
    34.     @Override  
    35.     protected void onDraw(Canvas canvas) {  
    36.         super.onDraw(canvas);  
    37.         canvas.drawXXX();  
    38.     }  
    39. }  

    下面是一个完整的例子(SDK 自带的例子):

    [java] view plaincopy
    1. import android.content.Context;  
    2. import android.content.res.TypedArray;  
    3. import android.graphics.Canvas;  
    4. import android.graphics.Paint;  
    5. import android.util.AttributeSet;  
    6. import android.view.View;  
    7.   
    8. public class LabelView extends View {  
    9.   
    10.     //第一步  
    11.     private String mText;  
    12.     private Paint mPaint;  
    13.     private int mAscent; /*此字段是在写类的过程中添加的,不是原先设计好的*/  
    14.       
    15.     //第二步  
    16.     public void setText(String text) {  
    17.         mText = text;  
    18.         /*  
    19.             在整个View的大小改变时需要调用 
    20.             此方法,调用此方法后会触发 onMeasure() 方法, 
    21.             重新计算和View相关的大小信息 
    22.         */  
    23.         requestLayout();  
    24.         /* 
    25.             当View的任何内容改变时(包括大小/样式/文字颜色)都 
    26.             需要调用此方法,调用此方法后会触发 onDraw() 方法 
    27.         */  
    28.         invalidate();  
    29.     }  
    30.     public void setTextColor(int color) {  
    31.         mPaint.setColor(color);  
    32.         /*只是改变字体颜色,不改变View大小,所以不用调用requestLayout*/  
    33.         invalidate();  
    34.     }  
    35.     public void setTextSize(int size) {  
    36.         mPaint.setTextSize(size);  
    37.         requestLayout();  
    38.         invalidate();  
    39.     }  
    40.     //第三步  
    41.     public LabelView(Context context) {  
    42.         super(context);  
    43.         initLabelView();  
    44.     }  
    45.     public LabelView(Context context, AttributeSet attrs) {  
    46.         super(context, attrs);  
    47.         initLabelView();  
    48.         /* 
    49.             Context.obtainStyledAttributes(AttributeSet set, int[] attrs) 
    50.             对于此方法第一个参数是XML文件中对此View的属性设置; 
    51.             第二个参数是在/res/valus/attrs.xml文件中定义的此文件的属性集合(包含许多属性) 
    52.         */  
    53.         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LableView);  
    54.         /* 
    55.             R.styleable.LableView_text是一个int[] attrs的一个下标值 
    56.         */  
    57.         String s = a.getString(R.styleable.LableView_text);  
    58.         if(s != null) {  
    59.             setText(s);  
    60.         }  
    61.         setTextColor(a.getColor(R.styleable.LableView_textColor, 0xFF000000));  
    62.         int textSize = a.getDimensionPixelOffset(R.styleable.LableView_textSize, 0);  
    63.         if(textSize > 0) {  
    64.             setTextSize(textSize);  
    65.         }  
    66.         a.recycle();  
    67.     }  
    68.     private void initLabelView() {  
    69.         mPaint = new Paint();  
    70.         mPaint.setColor(0xFF000000);  
    71.         mPaint.setTextSize(16);  
    72.         /* 使画出来的形状的"边沿"比较光滑 */  
    73.         mPaint.setAntiAlias(true);  
    74.         setPadding(3333);  
    75.     }  
    76.       
    77.     //第四步  
    78.     @Override  
    79.     /* 
    80.         此函数要决定这个View的大小,本View的Container会把widthMeasureSpec参数 
    81.         传入到此函数,注意widthMeasureSpec不是简单的一个整数,它代表了SpecMode/ 
    82.         SpecSize的信息 
    83.     */  
    84.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    85.         setMeasuredDimension(measureWidth(widthMeasureSpec),   
    86.                 measureHeight(heightMeasureSpec));  
    87.     }  
    88.     private int measureWidth(int widthMeasureSpec) {  
    89.         int result = 0;  
    90.         int specMode = MeasureSpec.getMode(widthMeasureSpec);  
    91.         int specSize = MeasureSpec.getSize(widthMeasureSpec);  
    92.         if(MeasureSpec.EXACTLY == specMode) {  
    93.             result = specSize;  
    94.         } else {  
    95.             result = (int)mPaint.measureText(mText) + getPaddingLeft()   
    96.                         + getPaddingRight();  
    97.             if(MeasureSpec.AT_MOST == specMode) {  
    98.                 result = Math.min(result, specSize);  
    99.             }  
    100.         }  
    101.         return result;  
    102.     }  
    103.     private int measureHeight(int heightMeasureSpec) {  
    104.         int result = 0;  
    105.         int specMode = MeasureSpec.getMode(heightMeasureSpec);  
    106.         int specSize = MeasureSpec.getSize(heightMeasureSpec);  
    107.         mAscent = (int)mPaint.ascent();  
    108.           
    109.         if(MeasureSpec.EXACTLY == specMode) {  
    110.             result = specSize;  
    111.         } else {  
    112.             result = -mAscent + (int)mPaint.descent() + getPaddingTop()   
    113.                         + getPaddingBottom();  
    114.             if(MeasureSpec.AT_MOST == specMode) {  
    115.                 result = Math.min(result, specSize);  
    116.             }  
    117.         }  
    118.         return result;  
    119.     }  
    120.       
    121.     //第五步  
    122.     @Override  
    123.     protected void onDraw(Canvas canvas) {  
    124.         super.onDraw(canvas);  
    125.         canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mPaint);  
    126.     }  
    127.   
    128. }  
    在 res/values/attrs.xml 中定义的 LabelView的相关 attr:

    [html] view plaincopy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <resources>  
    3.     <!-- declare-styleable是一个大组,编译为 R.styleable,且R.styleable中常量都为一个数组,数组中的值是 R.attr 中值 -->  
    4.     <!-- attr 为一个小属性,是declare-styleable的子元素,编译为 R.attrs -->  
    5.     <declare-styleable name="LableView">  
    6.         <attr name="text" format="string" />  
    7.         <attr name="textColor" format="color"/>  
    8.         <attr name="textSize" format="dimension"/>  
    9.     </declare-styleable>  
    10. </resources>  

    编译后的 R 文件为:

    [java] view plaincopy
    1. public static final class attr {  
    2.     public static final int text=0x7f010000;  
    3.     public static final int textColor=0x7f010001;  
    4.     public static final int textSize=0x7f010002;  
    5. }  
    [java] view plaincopy
    1. public static final class styleable {  
    2.     public static final int[] LableView = {  
    3.         0x7f0100000x7f0100010x7f010002  
    4.     };  
    5.   
    6.     //数组的下标,方便在代码中使用,工具自动生成  
    7.     public static final int LableView_text = 0;   
    8.     public static final int LableView_textColor = 1;  
    9.     public static final int LableView_textSize = 2;  
    10. };  
  • 相关阅读:
    盒子垂直水平居中
    Sahi (2) —— https/SSL配置(102 Tutorial)
    Sahi (1) —— 快速入门(101 Tutorial)
    组织分析(1)——介绍
    Java Servlet (1) —— Filter过滤请求与响应
    CAS (8) —— Mac下配置CAS到JBoss EAP 6.4(6.x)的Standalone模式(服务端)
    JBoss Wildfly (1) —— 7.2.0.Final编译
    CAS (7) —— Mac下配置CAS 4.x的JPATicketRegistry(服务端)
    CAS (6) —— Nginx代理模式下浏览器访问CAS服务器网络顺序图详解
    CAS (5) —— Nginx代理模式下浏览器访问CAS服务器配置详解
  • 原文地址:https://www.cnblogs.com/new0801/p/6175952.html
Copyright © 2011-2022 走看看