編輯:關於Android編程
/** * 該插件用於兼容ie6-7-8-9及現代浏覽器的異步上傳文件。 * 請注意,在ie6-7-8-9上面的原理是: * 新添加一個表單和一個iframe,然後每次選擇都將file輸入框復制到該表單上面,然後submit整個表單,這樣就可以實現類似ajax提交文件的效果, * 但是有一點是沒辦法處理的,就是在客戶端預覽圖片及判斷文件大小。現代浏覽器則可以。 */ var AjaxFileInput=function(opts){ var settings={ container:"" //放置input框的容器 ,inputFileElement:"" //input file的文件輸入框的elemnt,可以是jquery元素,也可以是dom元素。 請注意,由於每次上傳重新生成一個input輸入框到container裡面,所以建議container裡面除了file輸入框什麼都別放了。 ,onValidate:function(fileName,fileDom){ return true; } //這是選擇文件之後的驗證邏輯。假如返回true的話,那麼就可以繼續上傳圖片到服務端的某個url,否則不執行。 ,max_size:5*1024*1024 //限制上傳大小--注意,在ie6-9上面是沒辦法在客戶端獲取尺寸的,所以這種時候這個屬性相當於沒用。 ,url:"" //上傳時候的url。 ,beforeUpload:function(paras){ }//上傳文件之前會調用這個方法。你可以返回一個Object來,譬如:{birthday:"2016-2-05"}這樣,假如有這種形式的參數,那麼無論在兼容模式下面還是google等現代浏覽器的正常模式下面,該參數都會添加到表單然後上傳上去。 ,onError:function(errorMsg){ } ,onComplete:function(serverResult){ } }; $.extend(settings,opts); var _container=$(settings.container); var _currentFileButton={}; _currentFileButton=$(settings.inputFileElement); var _tpl_file_html=_container.html(); //獲取文本框的html,為以後替換新的文本框而做准備。 var userIEMode=false; if(window.FileReader==undefined){ userIEMode=true; } var innerTools={ getBase4FromImgFile:function(file,callBack){ var reader = new FileReader(); reader.onload = function(e) { var base64Img= e.target.result; //var $img = $('<img>').attr("src", e.target.result) //$('#preview').empty().append($img) if(callBack){ callBack(base64Img); } }; reader.readAsDataURL(file); } }; var _rid="rid_"+util.getRandomWords(5)+"_"+new Date().getTime(); var _form_id="form_"+_rid; var _ifr_id="ifr_"+_rid; var el_iframe={}; var el_form={}; var isBusy=false; var _i_app={ init:function(){ var me=this; if(userIEMode){ me.initIEForm(); } me.resetFileInput(settings.inputFileElement); } //--生成ie6-9必須的form表單和iframe來進行ajax異步提交。 ,initIEForm:function(){ var me=this; var _ifr_html='<iframe id="__ifr_id__" name="__ifr_id__" style="position: absolute; opacity: 0.0; visibility: visible; left:0;top:0; width:100px; height: 50px;"></iframe>'; _ifr_html=_ifr_html.replace(/__ifr_id__/g,_ifr_id); var _form_html='<form id="__form_id__" action="__url__" target="__ifr_id__" method="post" enctype="multipart/form-data" style="border: 1px solid;" ></form>'; _form_html=_form_html.replace(/__ifr_id__/g,_ifr_id); _form_html=_form_html.replace(/__form_id__/g,_form_id); _form_html=_form_html.replace(/__url__/g,settings.url); el_form=$(_form_html); el_iframe=$(_ifr_html); $(document.body).append(el_form); $(document.body).append(el_iframe); //--初始化iframe為ajax的相關操作。 me.initIFrameLoaded(); } //--初始化iframe onload的相關事件。 ,initIFrameLoaded:function(){ var me=this; var ifr_json=document.getElementById(_ifr_id); function handle_return(){ var doc = ifr_json.contentDocument || ifr_json.document; var _json_str=doc.body.innerText; var res={}; try{ res=JSON.parse(_json_str); isBusy=false; var _new_file_input=$(_tpl_file_html); me.resetFileInput(_new_file_input); _container.empty().append(_new_file_input); settings.onComplete(res); } catch(ex){ res=_json_str; isBusy=false; var _new_file_input=$(_tpl_file_html); me.resetFileInput(_new_file_input); _container.empty().append(_new_file_input); settings.onError(_json_str); } } if (ifr_json.attachEvent){ ifr_json.attachEvent("onload", function(){ handle_return(); }); } else { ifr_json.onload = function(){ handle_return(); }; } } //--上傳,用iframe及form方式。 ,uploadByForm:function(paras){ var me=this; el_form.empty(); el_form.append('<input type="submit" value="提交">'); for(var key in paras){ var _hide_val=$('<input type="hidden" value="" name="'+key+'">'); _hide_val.val(paras[key]); el_form.append(_hide_val); } if(util.checkEmpty(_currentFileButton.attr("name"))){ _currentFileButton.attr("name","file"); } el_form.append(_currentFileButton); setTimeout(function(){ el_form[0].submit(); },20); } ,uploadByHttpRequest:function(paras){ var me=this; var file=$(_currentFileButton)[0].files[0]; var xhr = new XMLHttpRequest(); function uploadFile() { var fd = new FormData(); var _uploadKey="file"; if(util.checkEmpty(_currentFileButton.attr("name"))==false){ _uploadKey=_currentFileButton.attr("name"); } fd.append(_uploadKey, file); for(var key in paras){ fd.append(key,paras[key]); } xhr.upload.addEventListener("progress", uploadProgress, false); xhr.addEventListener("load", uploadComplete, false); xhr.addEventListener("error", uploadFailed, false); xhr.addEventListener("abort", uploadCanceled, false); xhr.open("POST", settings.url); xhr.send(fd); } function uploadProgress(evt) { if (evt.lengthComputable) { var percentComplete = Math.round(evt.loaded * 100 / evt.total); //uploadItemObject.setProgress(percentComplete); //document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%'; } else { //document.getElementById('progressNumber').innerHTML = 'unable to compute'; //uploadItemObject.setStateTips("未知上傳進度"); } } function uploadComplete(evt) { /* This event is raised when the server send back a response */ //alert(evt.target.responseText); /*1.xhr.readyState:XMLHttpRequest狀態,等於4表示數據已經接收完畢 2.xhr.status:狀態碼,200表示正常 3.xhr.responseText:server回應的文字數據*/ //console.log(evt.target.status); //console.log(evt.target.readyState); //console.log(xhr.status); if(evt.target.status!=200){ isBusy=false; var _new_file_input=$(_tpl_file_html); me.resetFileInput(_new_file_input); _container.empty().append(_new_file_input); settings.onError(evt.target.status+"錯誤"); //uploadItemObject.showError(evt.target.status+"錯誤"); } else{ var res_json=""; try{ res_json=JSON.parse(evt.target.responseText); isBusy=false; var _new_file_input=$(_tpl_file_html); me.resetFileInput(_new_file_input); _container.empty().append(_new_file_input); settings.onComplete(res_json); } catch(ex){ res_json=evt.target.responseText; isBusy=false; var _new_file_input=$(_tpl_file_html); me.resetFileInput(_new_file_input); _container.empty().append(_new_file_input); settings.onError(res_json); } } } function uploadFailed(evt) { //alert("There was an error attempting to upload the file."); //uploadItemObject.showError(); settings.onError("上傳失敗"); } function uploadCanceled(evt) { //alert("The upload has been canceled by the user or the browser dropped the connection."); //uploadItemObject.showError(); } uploadFile(); isBusy=false; var _new_file_input=$(_tpl_file_html); me.resetFileInput(_new_file_input); _container.empty().append(_new_file_input); } //--重新設定上傳按鈕事件,請注意,假如要hack onchange事件的話,那麼這個方法調用是必不可少的。 ,resetFileInput:function(__file_input){ var me=this; var _fileInput=$(__file_input); var _fileDom=_fileInput[0]; _currentFileButton=_fileInput; $(_fileInput).change(function(){ //if(isBusy){ // return; //} //isBusy=true; var _fake_path=_fileDom.value; var __theFileName=""; if(util.checkEmpty(_fake_path)){ } else{ if(_fake_path.indexOf("\\")!=-1){ var arr2=_fake_path.split("\\"); __theFileName=arr2[arr2.length-1]; } else if(_fake_path.indexOf("/")!=-1){ var arr2=_fake_path.split("/"); __theFileName=arr2[arr2.length-1]; } } if(settings.onValidate(__theFileName,_fileDom)==false){ isBusy=false; var _new_file_input=$(_tpl_file_html); me.resetFileInput(_new_file_input); _container.empty().append(_new_file_input); return; } if(util.checkEmpty(_fake_path)==true){ var _new_file_input=$(_tpl_file_html); me.resetFileInput(_new_file_input); _container.empty().append(_new_file_input); return; } var _paras={ }; settings.beforeUpload(_paras); if(userIEMode){ me.uploadByForm(_paras); } else{ me.uploadByHttpRequest(_paras); } }); } }; _i_app.init(); }
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title></title> <jsp:include page="inc.js.jsp"></jsp:include> <script type="text/javascript" src="/static/vendor/AjaxFileInput/main.js"></script> </head> <body> <h1>file input文件上傳插件兼容處理---兼容ie6-11,chrome,ff,ipad,ios及安卓</h1> <input type="hidden" class="ipt" name="identityimagefront" id="identityimagefront"> <div style="position: relative;"> <img style="width: 108px; height: 108px;;" id="preview-front" ></span> <div id="front-container" style="position: absolute; left:0;top:0; opacity:0.0; width:108px;height:108px; cursor: pointer;border:1px solid green;background-color: slategray;"> <input type="file" id="file-chooser-front" style=" position: absolute; left:0;top:0; opacity:0.0; width:100%;height:100%; cursor: pointer; "/> </div> </div> <p class="tip mb10 ml90">支持 jpg , png , gif 大小在5M以內的圖片</p> <script> AjaxFileInput({ container:$("#front-container") ,inputFileElement:$("#file-chooser-front") ,url:"/service/singleImageUpload.jsp" ,onError:function(errorMsg){ var _notice=new NotificationFx({ type:"error" ,message:errorMsg }); _notice.show(); } ,onValidate:function(__theFileName,_fileDom){ if(util.checkEmpty(__theFileName)){ var _notice=new NotificationFx({ type:"error" ,message:"請選擇圖片" }); _notice.show(); return false; } if(!new RegExp("(jpg|jpeg|gif|png|bmp)+","gi").test(__theFileName)){ //alert("照片上傳:文件類型必須是JPG、JPEG、PNG或GIF!"); var _notice=new NotificationFx({ type:"error" ,message:"只支持jpg、jpeg、gif、png、bmp等圖片格式。" }); _notice.show(); return false; } if(_fileDom.files!=null&&_fileDom.files.length>0){ var oFile=_fileDom.files[0]; if(oFile.size>1024*1024*5){ //alert(settings.outOfSizeTips); var _notice=new NotificationFx({ type:"error" ,message:"最大只能上傳5Mb的圖片" }); _notice.show(); return false; } } return true; } ,onComplete:function(jsonObj){ if(jsonObj.error==0){ var _notice=new NotificationFx({ type:"success" ,message:"成功上傳" }); _notice.show(); $("#preview-front").attr("src",jsonObj.url); } else{ var _notice=new NotificationFx({ type:"error" ,message:"格式錯誤" }); _notice.show(); } } }); </script> </body> </html>
Android上讓人頭疼的莫過於從網絡上獲取圖片,然後顯示圖片,最後還要考慮到圖片的回收問題,這之間只要有任何一個環節有問題都可能直接OOM。尤其在需要展示圖片的列表頁面
本章內容第1節 線性布局第2節 相對布局第3節 幀布局第4節 表格布局第5節 網格布局 線性布局線性布局使用標簽進行配置,對應代碼中的類是android.wid
優化布局層次1.避免布局鑲嵌過深(如下) 我們完全可以去掉id為:main_ll_
前言今年真是熱補丁框架的洪荒之力爆發的一年,短短幾個月內,已經出現了好幾個熱修復的框架了,基本上都是大同小異,這裡我就不過多的去評論這些框架。只有自己真正的去經歷過,你才