由于前段时间项目中使用到了自动换行的线性布局,本来打算用表格布局在里面一个个的用Java代码添加ImageView的,但是添加的View控件是不确定的,因为得靠服务器的数据返回,就这样手动用Java代码画布局的方式就这样夭折了,因为在表哥布局中我无法确定一行显示多少个ImageView的数目,所以无法动态添加,最后自能自己去看看那种能够换行的线性布局了,线性布局比较不好的是不能自动换行,也就是当设置LinearLayout的orentation 设置为vertical 为竖直方向也就是只有一列,每行只能显示一个View或者View的子类,当设置LinearLayout的orentitation为Horizontal,LinearLayout的只能显示为一行,横向显示,当屏幕满了的时候,View控件并不会自动换行,所以我们要做的就是在LinearLayout满的时候自动换行。
需要了解的是怎么样绘制根据子控件的长宽绘制父控件的宽度与高度,所以需要传入的参数控件的高度,视图分为两种一种是View类型的,代表控件有TextView,Button,EditText 等等,还有一种是装视图的容器控件继承自ViewGroup的控件,如LinearLayout,RelativeLayout,TabHost等等控件,需要自动换行的线性布局的话,就需要根据子控件的高度与宽度,来动态加载父控件的高度与宽度,所以需要在构造函数中传入每一个子控件的固定的高度,或者是动态设置子控件的高度与宽度。
将自定义的LinearLayout 也继承自ViewGroup 并且重写抽象类ViewGrouop的几个方法:onMeasure(),onLayout(),dispathDraw() 三个方法的意思分别是:第一个onMeasure()是用来计算控件以及子控件所占用的区域,第二个onLayout()是控制子控件的换行,第三个可写可不写,主要是用来绘制控件的边框,
自定义LinearLayout的代码如下:
[java] view plaincopyprint
package comhuanglongmylinearlayout;
import androidcontentContext;
import androidgraphicsCanvas;
import androidgraphicsColor;
import androidgraphicsPaint;
import androidgraphicsRect;
import androidutilAttributeSet;
import androidviewView;
import androidviewViewGroup;
/
@author huanglong 2013-5-28 自定义自动换行LinearLayout
/
public class FixGridLayout extends ViewGroup {
private int mCellWidth;
private int mCellHeight;
public FixGridLayout(Context context) {
super(context);
}
public FixGridLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FixGridLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setmCellWidth(int w) {
mCellWidth = w;
requestLayout();
}
public void setmCellHeight(int h) {
mCellHeight = h;
requestLayout();
}
/
控制子控件的换行
/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int cellWidth = mCellWidth;
int cellHeight = mCellHeight;
int columns = (r - l) / cellWidth;
if (columns < 0) {
columns = 1;
}
int x = 0;
int y = 0;
int i = 0;
int count = getChildCount();
for (int j = 0; j < count; j++) {
final View childView = getChildAt(j);
// 获取子控件Child的宽高
int w = childViewgetMeasuredWidth();
int h = childViewgetMeasuredHeight();
// 计算子控件的顶点坐标
int left = x + ((cellWidth - w) / 2);
int top = y + ((cellHeight - h) / 2);
// int left = x;
// int top = y;
// 布局子控件
childViewlayout(left, top, left + w, top + h);
if (i >= (columns - 1)) {
i = 0;
x = 0;
y += cellHeight;
} else {
i++;
x += cellWidth;
}
}
}
/
计算控件及子控件所占区域
/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 创建测量参数
int cellWidthSpec = MeasureSpecmakeMeasureSpec(mCellWidth, MeasureSpecAT_MOST);
int cellHeightSpec = MeasureSpecmakeMeasureSpec(mCellHeight, MeasureSpecAT_MOST);
// 记录ViewGroup中Child的总个数
int count = getChildCount();
// 设置子空间Child的宽高
for (int i = 0; i < count; i++) {
View childView = getChildAt(i);
/
090 This is called to find out how big a view should be 091 The
parent supplies constraint information in the width and height
parameters 092 The actual mesurement work of a view is performed
in onMeasure(int, int), 093 called by this method 094 Therefore,
only onMeasure(int, int) can and must be overriden by subclasses
095
/
childViewmeasure(cellWidthSpec, cellHeightSpec);
}
// 设置容器控件所占区域大小
// 注意setMeasuredDimension和resolveSize的用法
setMeasuredDimension(resolveSize(mCellWidth count, widthMeasureSpec),
resolveSize(mCellHeight count, heightMeasureSpec));
// setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
// 不需要调用父类的方法
// superonMeasure(widthMeasureSpec, heightMeasureSpec);
}
/
为控件添加边框
/
@Override
protected void dispatchDraw(Canvas canvas) {
// 获取布局控件宽高
int width = getWidth();
int height = getHeight();
// 创建画笔
Paint mPaint = new Paint();
// 设置画笔的各个属性
mPaintsetColor(ColorBLUE);
mPaintsetStyle(PaintStyleSTROKE);
mPaintsetStrokeWidth(10);
mPaintsetAntiAlias(true);
// 创建矩形框
Rect mRect = new Rect(0, 0, width, height);
// 绘制边框
canvasdrawRect(mRect, mPaint);
// 最后必须调用父类的方法
superdispatchDraw(canvas);
}
}
然后在Xml文件中引用自己定义的控件,在Java代码中调用:
[java] view plaincopyprint
package comhuanglongmylinearlayout;
import androidosBundle;
import androidappActivity;
import androidviewMenu;
import androidviewMenuItem;
import androidwidgetCheckBox;
import androidwidgetSimpleAdapter;
import androidsupportv4appNavUtils;
public class MainActivity extends Activity {
private SimpleAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
superonCreate(savedInstanceState);
setContentView(Rlayoutactivity_main);
FixGridLayout fixGridLayout = (FixGridLayout) findViewById(Ridll);
fixGridLayoutsetmCellHeight(30);
fixGridLayoutsetmCellWidth(100);
for (int i = 0; i < 7; i++) {
CheckBox box = new CheckBox(MainActivitythis);
boxsetText("第"+i+"个");
fixGridLayoutaddView(box);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater()inflate(Rmenuactivity_main, menu);
return true;
}
}
getWidth在OnCreat的时候得到的是0。因为当一个view对象创建时,android并不知道其大小,所以getWidth()和 getHeight()返回的结果是0,真正大小是在计算布局时才会计算,所以会发现一个有趣的事,即在onDraw( ) 却能取得长宽的原因。
那怎么在onCreat 的时候得到呢
width = activitygetWindowManager()getDefaultDisplay()getWidth();
height = activitygetWindowManager()getDefaultDisplay()getHeight();
getMeasuredWidth必须在parent view或者它自己调用measure()函数之后才能得到 measure函数就是计算该函数需要占用的空间大小同理在设置view的长宽的时候,setWidth()很多情况下在onCreate方法中调用也会失效,要想设置成功,可以这样:
int >
View类是Android上面绘制单元的最小集合,是绘制 按键触发 已经可访问属性(可以理解为focus)的打包后的类ViewGroup类继承了View类 并且添加了对View的位置及逻辑的管理功能 构造了View之间各类关系至于Layout View的一个布局框架 组合了一系列的View
自已重写ViewPager就行了在onMeasure里做一下处理就可以实现自适应高度了
/自动适应高度的ViewPager
@author
/
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
childmeasure(widthMeasureSpec, MeasureSpecmakeMeasureSpec(0, MeasureSpecUNSPECIFIED));
int h = childgetMeasuredHeight();
if (h > height)
height = h;
}
heightMeasureSpec = MeasureSpecmakeMeasureSpec(height, MeasureSpecEXACTLY);
superonMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
在Microsoft Windows 中,键盘和鼠标是两个标准的用户输入源,在一些交叠的 *** 作中通常相互补充使用。当然,鼠标在今天的应用程序中比10年前使用得更为广泛。甚至在一些应用程序中,我们更习惯于使用鼠标,例如在游戏、画图程序、音乐程序,以及Web创览器等程序中就是这样。然而,我们可以不使用鼠标,但绝对不能从一般的PC中拆掉键盘。Windows程序获得键盘输入的方式:键盘输入以消息的形式传递给程序的窗口过程。实际上,第一次学习消息时,键盘就是一个明显的例子:消息应该传递给应用程序的信息类型。Windows用8种不同的消息来传递不同的键盘事件。这好像太多了,但是(就像我们所看到的一样)程序可以忽略其中至少一半的消息而不会有任何问题。并且,在大多数情况下,这些消息中包含的键盘信息会多于程序所需要的。处理键盘的部分工作就是识别出哪些消息是重要的,哪些是不重要的。键盘基础知识虽然应用程序在很多情况下可以通过鼠标实现信息的输入,但到现在为止键盘仍然是PC机中不可替代的重要输入设备。用键盘当作输入设备,每当用户按下或释放某一个键时,会产生一个中断,该中断激活键盘驱动程序KEYBOARDDRV来对键盘中断进行处理。 KEYBOARDDRV程序会根据用户的不同 *** 作进行编码,然后调用Windows用户模块USEREXE生成键盘消息,并将该消息发送到消息队列中等候处理。1.扫描码和虚拟码扫描码对应着键盘上的不同键,每一个键被按下或释放时,都会产生一个唯一的扫描码作为本身的标识。扫描码依赖于具体的硬件设备,即当相同的键被按下或释放时,在不同的机器上可能产生不同的扫描码。在程序中通常使用由Windows系统定义的与具体设备无关的虚拟码。在击键产生扫描码的同时,键盘驱动程序KEYBOARDDRV截取键的扫描码,然后将其翻译成对应的虚拟码,再将扫描码和虚拟码一齐编码形成键盘消息。所以,最后发送到消息队列的键盘消息中,既包含了扫描码又包含了虚拟码。经常使用的虚拟码在WINDOWS.H文件中定义,常用虚拟码的数值、常量符号和含义如表所示。取值(16进制) 常量符号 含义01 VK_LBUTTON 鼠标左键02 VK_RBUTTON 鼠标右键03 VK_CANCEL Break中断键04 VK_MBUTTON 鼠标中键05-07 -- 未定义08 VK_BACK (BackSpace)键09 VK_TAB Tab键0A-0B -- 未定义0C VK_CLEAR Clear键0D VK_RETURN Enter键0E-0F -- 未定义10 VK_SHIFT Shift键11 VK_CONTROL Ctrl键12 VK_MENU Alt键13 VK_PAUSE Pause键14 VK_CAPTIAL CapsLock键15-19 -- 汉字系统保留1A -- 未定义1B VK_ESCAPE Esc键1C-1F -- 汉字系统保留20 VK_SPACE 空格键21 VK_PRIOR PageUp键22 VK_NEXT PageDown键23 VK_END End键24 VK_HOME Home键25 VK_LEFT ←(Left Arrow)键26 VK_UP ↑(Up Arrow)键27 VK_RIGHT →(Right Arrow)键28 VK_DOWN ↓(Down Arrow)键29 VK_SELECT Select键2A -- OEM保留2B VK_EXECUTE Execute键2C VK_SNAPSHOT Print Screen键2D VK_INSERT Insert键2E VK_DELETE Delete键2F VK_HELP Help键30-39 VK_0-VK_9 数字键0-93A-40 -- 未定义41-5A VK_A-VK_Z 字母键A-Z5B-5F -- 未定义60-69 VK_NUMPAD0-VK_NUMPAD9 小键盘数字键0-96A VK_MULTIPLY (乘号)键6B VK_ADD +(加号)键6C VK_SEPAPATOR 分隔符键6E VK_SUBTRACT -(减号)键6F VK_DECIMAL (小数点)键70-87 VK_DIVIDE /(除号)键88-8F VK_F1-VK_F24 F1-F24功能键90 VK_NUMBERLOCK Number lock键91 VK_SCROLL Scroll lock键92-B9 -- 未定义BA-C0 -- OEM保留C1-DA -- 未定义DB_E4 -- OEM保留E5 -- 未定义E6 -- OEM保留E7-E8 -- 未定义E9-F5 -- OEM保留F6-FE -- 未定义2.输入焦点同一时刻,Windows中可能有多个不同的程序在运行,也就是说有多个窗口同时存在。这时,键盘由多个窗口共享,但只有一个窗口能够接收到键盘消息,这个能够接收键盘消息的窗口被称为拥有输入焦点的窗口。拥有输入焦点的窗口应该是当前的活动窗口,或者是活动窗口的子窗口,其标题和边框会以高亮度显示,以区别于其他窗口。拥有输入焦点的也可以是图标而不是窗口,此时,Windows也将消息发送给图标,只是消息的格式略有不同。窗口过程可以通过发送WM_SETFOCUS和 WM_KILLFOCUS消息使窗体获得或失去输入焦点。程序也可以通过捕获WM_SETFOCUS和WM_KILLFOCUS消息来判断窗体何时获得或失去输入焦点。其中WM_SETFOCUS消息表示窗口正获得输入焦点,WM_ KILLFOCUS消息表示窗口正失去输入焦点。3.键盘消息键盘消息分为系统键消息和非系统键消息。系统键消息是指由Aft键和其他键组合而产生的按键消息。当系统键被按下时产生WM_ SYSKEYDOWN消息,当系统键被释放时产生WM_SYSKEYUP消息。 Aft键与其他键形成的组合键通常用于对程序菜单和系统菜单进行选择,或用于在不同的程序之间进行切换。因此,系统键消息应该交由Windows进行处理,用户所编制的程序一般不处理系统键消息,而是将这些消息交由DefWindowProc函数进行处理。如果用户想对系统键消息进行处理,应该在处理完这些消息后,再将其发送给DefWindowProc函数,使得Windows系统能够正常工作。某些击键消息可以被转换成字符消息,例如字母键、数字键等。而有些键只能产生按键消息而没有字符消息,例如 Shift键、Insert键等。消息循环中的 TranslateMessage函数可以实现从击键消息向字符消息的转化。当GetMessage函数捕获一个WM_SYSKEYDOWN消息或 WM_KEYDOWN消息后,TranslateMessage函数判断产生该消息的键是否能够被转换成字符消息,如果能,就将该消息转换成字符消息,再通过DispatchMessape函数将转换后的字符消息发送到消息队列中去。字符消息共有以下四种,如表所示。字符 系统字符 非系统字符普通字符 WM_SYSCHAR WM_CHAR死字符 WM_SYSDEADCHAR WM_DEADCHAR其中死字符是由某些特殊键盘上的按键所造成的,Windows一般忽略死字符所产生的消息。Windows的消息一般是通过一个MSG结构体变量传送给消息处理函数的。对于键盘消息, MSG结构体变量的各个域中较重要的是lParam域和 wParam域。wParam域用于保存按键的虚拟键代码或字符的ASCII码。对于非字符消息,wParam域保存按键的虚拟健代码;对于字符消息, wParam域不保存字符的ASCII码。lParam域则用于保存击键时产生的附加信息,实际上一个32位的lParam变量被分为六部分,记录了以下相关信息:重复次数、OEM扫描码、扩展键标志、关联键标志、前一击键状态和转换状态。lParam域各位的含义如表所示。位数 含义0-15 击键重复次数累加16-23 OEM扫描码24 是否为扩展键25-28 未定义29 是否便用关联键,及Alt键是否同时按下。30 前一次击键状态,0表示该键前一次状态为抬起,1表示前一次状态为按下31 转换状态按键的次序不同,产生的消息也不相同。例如,按下并释放1键,读过程依次产生如表所示三条消息。按下1键所产生的消息和wParam的取值消息 wParam变量取值WM_KEYDOWN 虚拟码1WM_CHAR ASCII码“1”WM_KEYUP 虚拟码1如果按下Shift键后再按下1键并释放,则依次产生如表所示的消息。按下 Shift键后按 1健所产生的消息和 wParam的取值消息 wParam变量取值WM_KEYDOWN 虚拟码 VK_SHIFTWM_KEYDOWN 虚拟码 VK_1WM_CHAR ASCII码 “1”WM_KEYUP 虚拟码 VK_1WM_KEYUP 虚拟码 VK_SHIF键盘应用实例下面通过一个应用程序实例来说明在实际编程中如何处理键盘消息。#include <windowsh>#include <stdioh>// 全局变量RECT rc; //记录滚屏的矩形区域int xChar, yChar; //文本输入点坐标WNDCLASSEX wnd; //窗口类结构变量char szAppName[] = "键盘消息监视程序"; //窗口类名//函数声明LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);BOOL MyRegisterClass(HINSTANCE hInstance);BOOL InitInstance(HINSTANCE hInstance,int iCmdShow);//函数:WinMain//作用:入口函数int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow){MSG msg;if(!MyRegisterClass(hInstance)){return FALSE;} if(!InitInstance(hInstance,iCmdShow)){return FALSE;}while (GetMessage (&msg, NULL, 0, 0)){TranslateMessage (&msg);DispatchMessage (&msg);}return msgwParam;}//函数:ShowKey//作用:实现在窗口中显示按键信息void ShowKey (HWND hwnd, int iType,char szMessage,WPARAM wParam,LPARAM lParam){static char szFormat[2] ={"%-14s %3d %c %6u %4d %5s %5s %6s %6s", "%-14s %3d %c %6u %4d %5s %5s %6s %6s" };char szBuffer[80];HDC hdc;ScrollWindowEx(hwnd, 0, -yChar, &rc,&rc,NULL,NULL,SW_INVALIDATE);hdc = GetDC (hwnd);SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));TextOut (hdc, xChar, rcbottom - yChar, szBuffer, wsprintf szBuffer, szFormat[iType], szMessage, //消息 wParam, //虚拟键代码 (BYTE) (iType wParam :‘ ’),//显示字符值 LOWORD (lParam), // 重复次数 HIWORD (lParam) & 0xFF, // OEM键盘扫描码 //判断是否为增强键盘的扩展键 (PSTR) (0x01000000 & lParam “是” : “否”), //判断是否同时使用了ALT键 (PSTR) (0x20000000 & lParam “是” : “否”), (PSTR) (0x40000000 & lParam “按下” : “抬”), //判断前一次击键状 (PSTR)(0x80000000 & lParam “按下” : “抬起”)) //判断转换状态 );ReleaseDC (hwnd, hdc); ValidateRect (hwnd, NULL); }//函数:WndProc//作用:处理主窗口的消息LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam){static char szTop[] ="消息键 字符 重复数 扫描码 扩展码 ALT 前一状态 转换状态";static char szUnd[] ="_______ __ ____ _____ ______ ______ ___ _______ ______";//在窗口中输出文字作为信息标题HDC hdc;PAINTSTRUCT ps;TEXTMETRIC tm;switch (iMsg){case WM_CREATE://处理窗口创建的消息hdc = GetDC (hwnd); //设定字体SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)); //检取当前字体的度量数据GetTextMetrics (hdc, &tm);xChar = tmtmAveCharWidth;//保存字体平均宽度yChar = tmtmHeight; //保存字体高度ReleaseDC (hwnd, hdc);rctop = 3 yChar / 2;return 0;case WM_SIZE://处理窗口大小改变的消息//窗体改变后保存新的滚屏区域右下角坐标rcright = LOWORD (lParam);rcbottom = HIWORD (lParam);UpdateWindow (hwnd);return 0;case WM_PAINT: //处理窗口重绘消息InvalidateRect (hwnd, NULL, TRUE);hdc = BeginPaint (hwnd, &ps);SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;SetBkMode (hdc, TRANSPARENT) ;TextOut (hdc, xChar, yChar / 2, szTop, (sizeof szTop) - 1) ;TextOut (hdc, xChar, yChar / 2, szUnd, (sizeof szUnd) - 1) ;EndPaint (hwnd, &ps);return 0;case WM_KEYDOWN://处理键盘上某一键按下的消息ShowKey (hwnd, 0, "WM_KEYDOWN",wParam, lParam);return 0;case WM_KEYUP://处理键盘上某一按下键被释放的消息ShowKey (hwnd, 0, "WM_KEYUP", wParam, lParam);return 0;case WM_CHAR://处理击键过程中产生的非系统键的可见字符消息howKey (hwnd, 1, "WM_CHAR", wParam, lParam);return 0;case WM_DEADCHAR://处理击键过程中产生的非系统键"死字符"消息ShowKey (hwnd, 1, "WM_DEADCHAR", wParam, lParam);return 0;case WM_SYSKEYDOWN://处理系统键按下的消息ShowKey (hwnd, 0, "WM_SYSKEYDOWN",wParam, lParam);break;case WM_SYSKEYUP://处理系统键抬起的消息ShowKey (hwnd, 0, "WM_SYSKEYUP", wParam, lParam);break;case WM_SYSCHAR://处理系统键可见字符消息ShowKey (hwnd, 1, "WM_SYSCHAR", wParam, lParam);break;case WM_SYSDEADCHAR://处理系统键"死字符"消息ShowKey (hwnd, 1, "WM_SYSDEADCHAR", wParam, lParam);break;case WM_DESTROY://处理结束应用程序的消息PostQuitMessage (0);return 0;}return DefWindowProc (hwnd, iMsg, wParam, lParam);}//函数:MyRegisterClass//作用:注册窗口类BOOL MyRegisterClass(HINSTANCE hInstance){wndcbSize= sizeof (wnd);wndstyle = CS_HREDRAW CS_VREDRAW;wndlpfnWndProc = WndProc;wndcbClsExtra = 0;wndcbWndExtra = 0;wndhInstance = hInstance;wndhIcon = LoadIcon (NULL, IDI_APPLICATION);wndhCursor = LoadCursor (NULL, IDC_ARROW);wndhbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);wndlpszMenuName = NULL;wndlpszClassName = szAppName;wndhIconSm = LoadIcon (NULL, IDI_APPLICATION);return RegisterClassEx (&wnd);}//函数:InitInstance//作用:创建主窗口BOOL InitInstance(HINSTANCE hInstance,int iCmdShow){HWND hwnd;hwnd = CreateWindow (szAppName, "键盘消息监视程序", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL );if(!hwnd){return FALSE;}ShowWindow (hwnd, iCmdShow);UpdateWindow (hwnd);return TRUE;}
在看本文之前请写了解一下UNSPECIFIED、EXACTLY、AT_MOST三种模式。
在项目中经常会用到ScrollView嵌套ListView的情况。如果使用原生的ListView会出现只显示一行的情况:
出现这个的原因是在scrollView中ListView在OnMeasure阶段无法测出实际的高度,我们需要给他设置AT_MOST模式以支持很大的高度。这时候可以自定义一个MyListView 继承自Listview,然后重写onMeasure方法即可:
package comchuckcontactsdemo;
import androidcontentContext;
import androidutilAttributeSet;
import androidwidgetListView;
/
Created by chuck on 2015/11/26
/
public class MyListView extends ListView{
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
superonMeasure(widthMeasureSpec
,MeasureSpecmakeMeasureSpec(IntegerMAX_VALUE>>2,MeasureSpecAT_MOST));
}
}
1234567891011121314151617181920212223242526272829
从上边我们可以看出,我们没有改变widthMeasureSpec,仅仅是调用了makeMeasureSpec(IntegerMAX_VALUE>>2,MeasureSpecAT_MOST)方法,该方法会返回一个带有模式和大小信息的int值的,第一个参数IntegerMAX_VALUE >> 2,我们知道我们的控件的大小的最大值是用30位表示的(int占32位,其中前两位用来表示文章开头所说的三种模式)。那么IntegerMAX_VALUE来获取int值的最大值,然后右移2位,就得到这个最大值了 。因为是要最大值所以只能选择AT_MOST模式。最后 superonMeasure()方法将我们的高度值传进去就可以使ListView内容都展示出来了。
将布局文件中的ListView改成MyListView就ok了:
运用编程软件。
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){
intwidthSize=MeasureSpecgetSize(widthMeasureSpec);
intwidthMode=MeasureSpecgetMode(widthMeasureSpec);
inthighSize=MeasureSpecgetSize(heightMeasureSpec);
inthighMode=MeasureSpecgetMode(heightMeasureSpec);
intwidth=Mathmin(widthSize,highSize);//获取最小值来实现正方形布局
//防止出现尺寸为0不显示
if(widthMode==MeasureSpecUNSPECIFIED){
width=highSize;
}elseif(highMode==MeasureSpecUNSPECIFIED){
width=widthSize;
setMeasuredDimension(width,width);//设置宽高即正方形布局
以上就是关于android LinearLayout 里面的东西怎么换行全部的内容,包括:android LinearLayout 里面的东西怎么换行、Android中getWidth和getMeasureWidth的区别探究、第四轮问答题:View与ViewGroup有什么区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)