android開發中,能夠經過編寫XML格式的佈局文件來實現佈局,也能夠用純代碼進行佈局,一般都是選擇XML文件佈局。在XML佈局文件中,與控件的尺寸有關的屬性有android:minHeight、android:minWidth、android:layout_weight、android:layout_width等。像layout_width、layout_height既能夠指定具體的數值,也能夠指定wrap_content、match_parent這樣的值,並且有時候獲得的與指定的可能不一致,那麼控件的尺寸到底怎麼肯定?查閱Android文檔,在類View中能夠找到這麼一段話: html
The size of a view is expressed with a width and a height. A view actually possess two pairs of width and height values. java
The first pair is known as measured width and measured height. These dimensions define how big a view wants to be within its parent (see Layout for more details.) The measured dimensions can be obtained by callinggetMeasuredWidth()andgetMeasuredHeight(). android
The second pair is simply known as width and height, or sometimes drawing width and drawing height. These dimensions define the actual size of the view on screen, at drawing time and after layout. These values may, but do not have to, be different from the measured width and height. The width and height can be obtained by callinggetWidth()andgetHeight(). express
也就是說,一個View實際有兩個尺寸,一個是它想要的尺寸,一個是它實際上的尺寸。一個View的onDraw方法被調用前,會調用onMeasure (int widthMeasureSpec, int heightMeasureSpec)方法來獲得一個想要的尺寸。若是沒有指定尺寸相關的屬性,也沒有重寫onMeasure方法,默認的尺寸是100x100.在onMeasure方法中,必須調用setMeasuredDimension(int, int)方法來設定測量好的寬高值。具體更詳細的用法以及各個參數的含義能夠查閱文檔,這裏給一個簡單的重寫示例: apache
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int wMode = MeasureSpec.getMode(widthMeasureSpec);
int hMode = MeasureSpec.getMode(heightMeasureSpec); tomcat
if (wMode == MeasureSpec.AT_MOST)
mWidth = MeasureSpec.getSize(widthMeasureSpec);
else
mWidth = 320;
if (hMode == MeasureSpec.AT_MOST)
mHeight = MeasureSpec.getSize(heightMeasureSpec);
else
mHeight = 240; 服務器
this.setMeasuredDimension(mWidth, mHeight);
} socket
至於爲何實際尺寸與測量的尺寸每每不一致,官方文檔解釋,在測量的時候,把控件間的padding也計算在內了,而實際尺寸是不會包含padding的。 ide
最後,貼一張網上扒來的圖,這張圖很好地揭示了控件的繪製過程: 佈局
參考文章:
[1]Android中View繪製流程以及invalidate()等相關方法分析
在android開發中,須要將文件上傳到服務器。傳文件寫個簡單的socket固然也能搞定,可是讓功能強大的服務器跑一個本身寫的低端socket server豈不是笑話,乖乖使用現成的服務器程序吧。發現http協議支持文件上傳,因而事情就簡單多了,查了些資料,抄了份servlet代碼又簡單改了改,跑在了tomcat上:
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.xxx.config.PathConfig; //這個類裏有一些靜態的路徑配置信息
/**
* Servlet implementation class FileUpload
*/
@WebServlet(description = "A servelt for uploading files", urlPatterns = {
"/FileUpload", "/upload" })
public class FileUpload extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public FileUpload() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items) {
if (!item.isFormField()) {
item.write(new File(PathConfig.UPLOAD_PATH, //這是我設置的目錄
item.getName().substring(
item.getName().lastIndexOf("\\") + 1)));
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
這段代碼裏用到了apache的FileUpload包,而後它自身又須要commons-io.jar,具體下載地址能夠在這裏找到http://commons.apache.org/proper/commons-fileupload/.
servlet在tomcat上跑起來後,能夠寫個簡單的html頁面在本地上測試一下:
<html>
<body>
<h1>File API Demo</h1>
<p>
<!-- 用於文件上傳的表單元素 -->
<form name="demoForm" id="demoForm" method="post" enctype="multipart/form-data"
action="http://localhost:8080/upload">
<p>Upload File: <input type="file" name="file" /></p>
<p><input type="submit" value="Submit" /></p>
</form>
</body>
</html>
至於android上的文件上傳客戶端……由於我按照參考文章裏的第二個方案並無成功,因此等我解決了神祕的錯誤再說吧:-)
參考文章: