android开发中,可能会导致内存泄露的问题

在android编码中,会有一些简便的写法和编码习惯,会导致我们的代码有很多内存泄露的问题。 在这里做一个已知错误的总结(其中有一些是个人总结和参考其他博主的文章,在此表示感谢)。 本文会不定时更新,将自己遇到的内存泄漏相关的问题记录下来并提供解决办法。 1,编写单例的时候常出现的错误。 错误方式: public class Foo{ private static Foo foo; private Context mContext; private Foo(Context mContext){ this.mContext = mContext; } // 普通单例,非线程安全 public static Foo getInstance(Context mContext){ if(foo == null) foo = new Foo(mContext); return foo; } public void otherAction(){ mContext.xxxx(); …. } } 错误原因: 如果我们在Activity A中或者其他地方使用Foo.getInstance()时,我们总是会顺手写一个『this』或者『mContext』(这个变量也是指向this)。试想一下,当前我们所用的Foo是单例,意味着被初始化后会一直存在与内存中,以方便我们以后调用的时候不会在此次创建Foo对象。但Foo中的『mContext』变量一直都会持有Activity A中的『Context』,导致Activity A即使执行了onDestroy方法,也不能够将自己销毁。但『applicationContext』就不同了,它一直伴随着我们应用存在(中途也可能会被销毁,但也会自动reCreate),所以就不用担心Foo中的『mContext』会持有某Activity的引用,让其无法销毁。 正确方式: public class Foo{ private static Foo foo; private Context mContext; private Foo(Context mContext){ this.mContext = mContext; } // 普通单例,非线程安全 public static Foo getInstance(Context mContext){ ...

2015年5月27日 · 2 分钟 · 天边的星星

听FackBook工程师讲Custom ViewGroups

原文链接 : [Custom ViewGroups][1] 原文作者 : [Sriram Ramani][2] Android提供了几个ViewGroups如LinearLayout, RelativeLayout, FrameLayout来固定child Views的位置。在这些普通的ViewGroups中有多种使用选择。 例如:LinearLayout几乎支持HTML Flexbox的所有特性(除了包装)。在view之间你可以选择是否显示分割线(dividers),并且基于最大的child测量所有的children。RelativeLayout是一种限制性的解决方案。这些layouts都已经足够好了,但是当你的UI非常复杂的时候它们还能很好的解决么? ViewGroup with a ProfilePhoto, Title, Subtitle and Menu button. 上面的这种布局在Facebook app中是非常常见的。有头像、其它的view垂直摆在它的右侧、还有一个可选操作的view在最右边。这个布局可以通过使用LinearLayout嵌套或者一个RelativeLayout这样的普通ViewGroup实现。我们看一下当分别使用这两种布局的情况下在measure时会发生什么。 使用LinearLayout完成布局的示例 ``` <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <span class="pl-k">&lt;</span><span class="pl-smi">ProfilePhoto</span> android<span class="pl-k">:</span>layout_width<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>40dp<span class="pl-pds">"</span></span> android<span class="pl-k">:</span>layout_height<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>40dp<span class="pl-pds">"</span></span><span class="pl-k">/</span><span class="pl-k">&gt;</span> <span class="pl-k">&lt;</span><span class="pl-smi">LinearLayout</span> android<span class="pl-k">:</span>layout_width<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>0dp<span class="pl-pds">"</span></span> android<span class="pl-k">:</span>layout_height<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>wrap_content<span class="pl-pds">"</span></span> android<span class="pl-k">:</span>layout_weight<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>1<span class="pl-pds">"</span></span> android<span class="pl-k">:</span>orientation<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>vertical<span class="pl-pds">"</span></span><span class="pl-k">&gt;</span> <span class="pl-k">&lt;</span><span class="pl-smi">Title</span> android<span class="pl-k">:</span>layout_width<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>match_parent<span class="pl-pds">"</span></span> android<span class="pl-k">:</span>layout_height<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>wrap_content<span class="pl-pds">"</span></span><span class="pl-k">/</span><span class="pl-k">&gt;</span> <span class="pl-k">&lt;</span><span class="pl-smi">Subtitle</span> android<span class="pl-k">:</span>layout_width<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>match_parent<span class="pl-pds">"</span></span> android<span class="pl-k">:</span>layout_height<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>wrap_content<span class="pl-pds">"</span></span><span class="pl-k">/</span><span class="pl-k">&gt;</span> <span class="pl-k">&lt;</span><span class="pl-k">/</span><span class="pl-smi">LinearLayout</span><span class="pl-k">&gt;</span> <span class="pl-k">&lt;</span><span class="pl-smi">Menu</span> android<span class="pl-k">:</span>layout_width<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>20dp<span class="pl-pds">"</span></span> android<span class="pl-k">:</span>layout_height<span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>20dp<span class="pl-pds">"</span></span><span class="pl-k">/</span><span class="pl-k">&gt;</span> </LinearLayout> ...

2015年5月27日 · 5 分钟 · 天边的星星

Android WebView 总结

1、添加权限:AndroidManifest.xml中必须使用许可”android.permission.INTERNET”,否则会出Web page not available错误。 2、在要Activity中生成一个WebView组件:WebView webView = new WebView(this); 3、设置WebView基本信息: 如果访问的页面中有Javascript,则webview必须设置支持Javascript。 webview.getSettings().setJavaScriptEnabled(true); 触摸焦点起作用 requestFocus(); 取消滚动条 this.setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY); 4、设置WevView要显示的网页: 互联网用:webView.loadUrl(“http://www.google.com”); 本地文件用:webView.loadUrl(“file:///android_asset/XX.html”); 本地文件存放在:assets文件中 5、如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。 给WebView添加一个事件监听对象(WebViewClient) 并重写其中的一些方法 shouldOverrideUrlLoading:对网页中超链接按钮的响应。 当按下某个连接时WebViewClient会调用这个方法,并传递参数:按下的url onLoadResource onPageStart onPageFinish onReceiveError onReceivedHttpAuthRequest 6、如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消费掉该Back事件。 覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。 [?](http://www.oschina.net/question/163910_26516#) <table border="0" cellspacing="0" cellpadding="0"> <tr> <td class="gutter"> <div class="line number1 index0 alt2"> 1 </div> <div class="line number2 index1 alt1"> 2 </div> <div class="line number3 index2 alt2"> 3 </div> <div class="line number4 index3 alt1"> 4 </div> <div class="line number5 index4 alt2"> 5 </div> <div class="line number6 index5 alt1"> 6 </div> <div class="line number7 index6 alt2"> 7 </div> <div class="line number8 index7 alt1"> 8 </div> </td> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"> `public` `boolean` `onKeyDown(``int` `keyCoder,KeyEvent event){` </div> <div class="line number2 index1 alt1"> ` ``if``(webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){` </div> <div class="line number3 index2 alt2"> ` ``webview.goBack(); ``//goBack()表示返回webView的上一页面` </div> <div class="line number4 index3 alt1"> </div> <div class="line number5 index4 alt2"> ` ``return` `true``;` </div> <div class="line number6 index5 alt1"> ` ``}` </div> <div class="line number7 index6 alt2"> ` ``return` `false``;` </div> <div class="line number8 index7 alt1"> `}` </div> </div> </td> </tr> </table> &nbsp; ### Android监听WebView滑动到底部 MainActivity如下: <div> <div id="highlighter_5859" class="syntaxhighlighter java"> <div class="toolbar"> [?](http://www.open-open.com/lib/view/open1379383341959.html#) </div> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td class="gutter"> <div class="line number1 index0 alt2"> 1 </div> <div class="line number2 index1 alt1"> 2 </div> <div class="line number3 index2 alt2"> 3 </div> <div class="line number4 index3 alt1"> 4 </div> <div class="line number5 index4 alt2"> 5 </div> <div class="line number6 index5 alt1"> 6 </div> <div class="line number7 index6 alt2"> 7 </div> <div class="line number8 index7 alt1"> 8 </div> <div class="line number9 index8 alt2"> 9 </div> <div class="line number10 index9 alt1"> 10 </div> <div class="line number11 index10 alt2"> 11 </div> <div class="line number12 index11 alt1"> 12 </div> <div class="line number13 index12 alt2"> 13 </div> <div class="line number14 index13 alt1"> 14 </div> <div class="line number15 index14 alt2"> 15 </div> <div class="line number16 index15 alt1"> 16 </div> <div class="line number17 index16 alt2"> 17 </div> <div class="line number18 index17 alt1"> 18 </div> <div class="line number19 index18 alt2"> 19 </div> <div class="line number20 index19 alt1"> 20 </div> <div class="line number21 index20 alt2"> 21 </div> <div class="line number22 index21 alt1"> 22 </div> <div class="line number23 index22 alt2"> 23 </div> <div class="line number24 index23 alt1"> 24 </div> <div class="line number25 index24 alt2"> 25 </div> <div class="line number26 index25 alt1"> 26 </div> <div class="line number27 index26 alt2"> 27 </div> <div class="line number28 index27 alt1"> 28 </div> <div class="line number29 index28 alt2"> 29 </div> <div class="line number30 index29 alt1"> 30 </div> <div class="line number31 index30 alt2"> 31 </div> <div class="line number32 index31 alt1"> 32 </div> <div class="line number33 index32 alt2"> 33 </div> <div class="line number34 index33 alt1"> 34 </div> <div class="line number35 index34 alt2"> 35 </div> <div class="line number36 index35 alt1"> 36 </div> <div class="line number37 index36 alt2"> 37 </div> <div class="line number38 index37 alt1"> 38 </div> <div class="line number39 index38 alt2"> 39 </div> <div class="line number40 index39 alt1"> 40 </div> <div class="line number41 index40 alt2"> 41 </div> <div class="line number42 index41 alt1"> 42 </div> <div class="line number43 index42 alt2"> 43 </div> <div class="line number44 index43 alt1"> 44 </div> <div class="line number45 index44 alt2"> 45 </div> <div class="line number46 index45 alt1"> 46 </div> <div class="line number47 index46 alt2"> 47 </div> <div class="line number48 index47 alt1"> 48 </div> <div class="line number49 index48 alt2"> 49 </div> <div class="line number50 index49 alt1"> 50 </div> <div class="line number51 index50 alt2"> 51 </div> <div class="line number52 index51 alt1"> 52 </div> <div class="line number53 index52 alt2"> 53 </div> <div class="line number54 index53 alt1"> 54 </div> <div class="line number55 index54 alt2"> 55 </div> <div class="line number56 index55 alt1"> 56 </div> <div class="line number57 index56 alt2"> 57 </div> <div class="line number58 index57 alt1"> 58 </div> <div class="line number59 index58 alt2"> 59 </div> <div class="line number60 index59 alt1"> 60 </div> <div class="line number61 index60 alt2"> 61 </div> <div class="line number62 index61 alt1"> 62 </div> <div class="line number63 index62 alt2"> 63 </div> <div class="line number64 index63 alt1"> 64 </div> <div class="line number65 index64 alt2"> 65 </div> <div class="line number66 index65 alt1"> 66 </div> <div class="line number67 index66 alt2"> 67 </div> <div class="line number68 index67 alt1"> 68 </div> <div class="line number69 index68 alt2"> 69 </div> <div class="line number70 index69 alt1"> 70 </div> <div class="line number71 index70 alt2"> 71 </div> <div class="line number72 index71 alt1"> 72 </div> <div class="line number73 index72 alt2"> 73 </div> <div class="line number74 index73 alt1"> 74 </div> <div class="line number75 index74 alt2"> 75 </div> <div class="line number76 index75 alt1"> 76 </div> <div class="line number77 index76 alt2"> 77 </div> <div class="line number78 index77 alt1"> 78 </div> <div class="line number79 index78 alt2"> 79 </div> <div class="line number80 index79 alt1"> 80 </div> <div class="line number81 index80 alt2"> 81 </div> <div class="line number82 index81 alt1"> 82 </div> <div class="line number83 index82 alt2"> 83 </div> <div class="line number84 index83 alt1"> 84 </div> <div class="line number85 index84 alt2"> 85 </div> <div class="line number86 index85 alt1"> 86 </div> <div class="line number87 index86 alt2"> 87 </div> <div class="line number88 index87 alt1"> 88 </div> <div class="line number89 index88 alt2"> 89 </div> <div class="line number90 index89 alt1"> 90 </div> <div class="line number91 index90 alt2"> 91 </div> </td> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"> `package` `cn.testwebview;` </div> <div class="line number2 index1 alt1"> `import` `android.app.Activity;` </div> <div class="line number3 index2 alt2"> `import` `android.graphics.Bitmap;` </div> <div class="line number4 index3 alt1"> `import` `android.os.Bundle;` </div> <div class="line number5 index4 alt2"> `import` `android.webkit.WebSettings;` </div> <div class="line number6 index5 alt1"> `import` `android.webkit.WebView;` </div> <div class="line number7 index6 alt2"> `import` `android.webkit.WebViewClient;` </div> <div class="line number8 index7 alt1"> `import` `cn.testwebview.TestWebView.ScrollInterface;` </div> <div class="line number9 index8 alt2"> `/**` </div> <div class="line number10 index9 alt1"> ` ``* Demo描述:` </div> <div class="line number11 index10 alt2"> ` ``* 监听WebView滑动到底部` </div> <div class="line number12 index11 alt1"> ` ``*` </div> <div class="line number13 index12 alt2"> ` ``* 参考资料:` </div> <div class="line number14 index13 alt1"> ` ``* 1 http://blog.csdn.net/conant1989/article/details/8124582` </div> <div class="line number15 index14 alt2"> ` ``* Thank you very much` </div> <div class="line number16 index15 alt1"> ` ``*/` </div> <div class="line number17 index16 alt2"> `public` `class` `MainActivity ``extends` `Activity {` </div> <div class="line number18 index17 alt1"> ` ``private` `TestWebView mTestWebView;` </div> <div class="line number19 index18 alt2"> ` ``@Override` </div> <div class="line number20 index19 alt1"> ` ``protected` `void` `onCreate(Bundle savedInstanceState) {` </div> <div class="line number21 index20 alt2"> ` ``super``.onCreate(savedInstanceState);` </div> <div class="line number22 index21 alt1"> ` ``setContentView(R.layout.main);` </div> <div class="line number23 index22 alt2"> ` ``initWebView();` </div> <div class="line number24 index23 alt1"> ` ``}` </div> <div class="line number25 index24 alt2"> ` ` </div> <div class="line number26 index25 alt1"> ` ` </div> <div class="line number27 index26 alt2"> ` ` </div> <div class="line number28 index27 alt1"> ` ``//设置WebView` </div> <div class="line number29 index28 alt2"> ` ``private` `void` `initWebView() {` </div> <div class="line number30 index29 alt1"> ` ``mTestWebView = (TestWebView) findViewById(R.id.webView);` </div> <div class="line number31 index30 alt2"> ` ``mTestWebView.setVerticalScrollBarEnabled(``true``);` </div> <div class="line number32 index31 alt1"> ` ``mTestWebView.setHorizontalScrollBarEnabled(``false``);` </div> <div class="line number33 index32 alt2"> ` ``mTestWebView.getSettings().setSupportZoom(``true``);` </div> <div class="line number34 index33 alt1"> ` ``mTestWebView.getSettings().setBuiltInZoomControls(``true``);` </div> <div class="line number35 index34 alt2"> ` ``mTestWebView.getSettings().setJavaScriptEnabled(``true``);` </div> <div class="line number36 index35 alt1"> ` ` </div> <div class="line number37 index36 alt2"> ` ``mTestWebView.getSettings().setDomStorageEnabled(``true``);` </div> <div class="line number38 index37 alt1"> ` ``mTestWebView.getSettings().setPluginsEnabled(``true``);` </div> <div class="line number39 index38 alt2"> ` ``mTestWebView.requestFocus();` </div> <div class="line number40 index39 alt1"> ` ` </div> <div class="line number41 index40 alt2"> ` ``mTestWebView.getSettings().setUseWideViewPort(``true``);` </div> <div class="line number42 index41 alt1"> ` ``mTestWebView.getSettings().setLoadWithOverviewMode(``true``);` </div> <div class="line number43 index42 alt2"> ` ``mTestWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);` </div> <div class="line number44 index43 alt1"> ` ` </div> <div class="line number45 index44 alt2"> ` ``mTestWebView.loadUrl(``"http://www.ifeng.com"``);` </div> <div class="line number46 index45 alt1"> ` ``mTestWebView.setWebViewClient(``new` `TestWebViewClient());` </div> <div class="line number47 index46 alt2"> ` ``webViewScroolChangeListener();` </div> <div class="line number48 index47 alt1"> ` ` </div> <div class="line number49 index48 alt2"> ` ``}` </div> <div class="line number50 index49 alt1"> ` ` </div> <div class="line number51 index50 alt2"> ` ``//核心代码` </div> <div class="line number52 index51 alt1"> ` ``private` `void` `webViewScroolChangeListener() {` </div> <div class="line number53 index52 alt2"> ` ``mTestWebView.setOnCustomScroolChangeListener(``new` `ScrollInterface() {` </div> <div class="line number54 index53 alt1"> ` ``@Override` </div> <div class="line number55 index54 alt2"> ` ``public` `void` `onSChanged(``int` `l, ``int` `t, ``int` `oldl, ``int` `oldt) {` </div> <div class="line number56 index55 alt1"> ` ``//WebView的总高度` </div> <div class="line number57 index56 alt2"> ` ``float` `webViewContentHeight=mTestWebView.getContentHeight() * mTestWebView.getScale();` </div> <div class="line number58 index57 alt1"> ` ``//WebView的现高度` </div> <div class="line number59 index58 alt2"> ` ``float` `webViewCurrentHeight=(mTestWebView.getHeight() + mTestWebView.getScrollY());` </div> <div class="line number60 index59 alt1"> ` ``System.out.println(``"webViewContentHeight="``+webViewContentHeight);` </div> <div class="line number61 index60 alt2"> ` ``System.out.println(``"webViewCurrentHeight="``+webViewCurrentHeight);` </div> <div class="line number62 index61 alt1"> ` ``if` `((webViewContentHeight-webViewCurrentHeight) == ````) {` </div> <div class="line number63 index62 alt2"> ` ``System.out.println(``"WebView滑动到了底端"``);` </div> <div class="line number64 index63 alt1"> ` ``}` </div> <div class="line number65 index64 alt2"> ` ``}` </div> <div class="line number66 index65 alt1"> ` ``});` </div> <div class="line number67 index66 alt2"> ` ``}` </div> <div class="line number68 index67 alt1"> ` ` </div> <div class="line number69 index68 alt2"> </div> <div class="line number70 index69 alt1"> ` ``private` `class` `TestWebViewClient ``extends` `WebViewClient{` </div> <div class="line number71 index70 alt2"> ` ``@Override` </div> <div class="line number72 index71 alt1"> ` ``public` `void` `onPageStarted(WebView view, String url, Bitmap favicon) {` </div> <div class="line number73 index72 alt2"> ` ``super``.onPageStarted(view, url, favicon);` </div> <div class="line number74 index73 alt1"> ` ``}` </div> <div class="line number75 index74 alt2"> ` ``@Override` </div> <div class="line number76 index75 alt1"> ` ``public` `boolean` `shouldOverrideUrlLoading(WebView view, String url) {` </div> <div class="line number77 index76 alt2"> ` ``view.loadUrl(url);` </div> <div class="line number78 index77 alt1"> ` ``return` `true``;` </div> <div class="line number79 index78 alt2"> ` ``}` </div> <div class="line number80 index79 alt1"> ` ``@Override` </div> <div class="line number81 index80 alt2"> ` ``public` `void` `onPageFinished(WebView view, String url) {` </div> <div class="line number82 index81 alt1"> ` ``super``.onPageFinished(view, url);` </div> <div class="line number83 index82 alt2"> ` ` </div> <div class="line number84 index83 alt1"> ` ``}` </div> <div class="line number85 index84 alt2"> ` ``@Override` </div> <div class="line number86 index85 alt1"> ` ``public` `void` `onReceivedError(WebView view, ``int` `errorCode,String description, String failingUrl) {` </div> <div class="line number87 index86 alt2"> ` ``super``.onReceivedError(view, errorCode, description, failingUrl);` </div> <div class="line number88 index87 alt1"> ` ``}` </div> <div class="line number89 index88 alt2"> ` ``}` </div> <div class="line number90 index89 alt1"> ` ` </div> <div class="line number91 index90 alt2"> `}` </div> </div> </td> </tr> </table> </div> </div> TestWebView如下: <div> <div id="highlighter_625536" class="syntaxhighlighter java"> <div class="toolbar"> [?](http://www.open-open.com/lib/view/open1379383341959.html#) </div> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td class="gutter"> <div class="line number1 index0 alt2"> 1 </div> <div class="line number2 index1 alt1"> 2 </div> <div class="line number3 index2 alt2"> 3 </div> <div class="line number4 index3 alt1"> 4 </div> <div class="line number5 index4 alt2"> 5 </div> <div class="line number6 index5 alt1"> 6 </div> <div class="line number7 index6 alt2"> 7 </div> <div class="line number8 index7 alt1"> 8 </div> <div class="line number9 index8 alt2"> 9 </div> <div class="line number10 index9 alt1"> 10 </div> <div class="line number11 index10 alt2"> 11 </div> <div class="line number12 index11 alt1"> 12 </div> <div class="line number13 index12 alt2"> 13 </div> <div class="line number14 index13 alt1"> 14 </div> <div class="line number15 index14 alt2"> 15 </div> <div class="line number16 index15 alt1"> 16 </div> <div class="line number17 index16 alt2"> 17 </div> <div class="line number18 index17 alt1"> 18 </div> <div class="line number19 index18 alt2"> 19 </div> <div class="line number20 index19 alt1"> 20 </div> <div class="line number21 index20 alt2"> 21 </div> <div class="line number22 index21 alt1"> 22 </div> <div class="line number23 index22 alt2"> 23 </div> <div class="line number24 index23 alt1"> 24 </div> <div class="line number25 index24 alt2"> 25 </div> <div class="line number26 index25 alt1"> 26 </div> <div class="line number27 index26 alt2"> 27 </div> <div class="line number28 index27 alt1"> 28 </div> <div class="line number29 index28 alt2"> 29 </div> <div class="line number30 index29 alt1"> 30 </div> <div class="line number31 index30 alt2"> 31 </div> <div class="line number32 index31 alt1"> 32 </div> <div class="line number33 index32 alt2"> 33 </div> <div class="line number34 index33 alt1"> 34 </div> <div class="line number35 index34 alt2"> 35 </div> <div class="line number36 index35 alt1"> 36 </div> <div class="line number37 index36 alt2"> 37 </div> <div class="line number38 index37 alt1"> 38 </div> <div class="line number39 index38 alt2"> 39 </div> <div class="line number40 index39 alt1"> 40 </div> <div class="line number41 index40 alt2"> 41 </div> <div class="line number42 index41 alt1"> 42 </div> <div class="line number43 index42 alt2"> 43 </div> </td> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"> `package` `cn.testwebview;` </div> <div class="line number2 index1 alt1"> </div> <div class="line number3 index2 alt2"> `import` `android.content.Context;` </div> <div class="line number4 index3 alt1"> `import` `android.util.AttributeSet;` </div> <div class="line number5 index4 alt2"> `import` `android.webkit.WebView;` </div> <div class="line number6 index5 alt1"> </div> <div class="line number7 index6 alt2"> `public` `class` `TestWebView ``extends` `WebView {` </div> <div class="line number8 index7 alt1"> ` ``public` `ScrollInterface mScrollInterface;` </div> <div class="line number9 index8 alt2"> </div> <div class="line number10 index9 alt1"> ` ``public` `TestWebView(Context context) {` </div> <div class="line number11 index10 alt2"> ` ``super``(context);` </div> <div class="line number12 index11 alt1"> ` ``}` </div> <div class="line number13 index12 alt2"> </div> <div class="line number14 index13 alt1"> ` ``public` `TestWebView(Context context, AttributeSet attrs, ``int` `defStyle) {` </div> <div class="line number15 index14 alt2"> ` ``super``(context, attrs, defStyle);` </div> <div class="line number16 index15 alt1"> ` ``}` </div> <div class="line number17 index16 alt2"> </div> <div class="line number18 index17 alt1"> ` ``public` `TestWebView(Context context, AttributeSet attrs) {` </div> <div class="line number19 index18 alt2"> ` ``super``(context, attrs);` </div> <div class="line number20 index19 alt1"> ` ``}` </div> <div class="line number21 index20 alt2"> </div> <div class="line number22 index21 alt1"> ` ``@Override` </div> <div class="line number23 index22 alt2"> ` ``protected` `void` `onScrollChanged(``int` `l, ``int` `t, ``int` `oldl, ``int` `oldt) {` </div> <div class="line number24 index23 alt1"> </div> <div class="line number25 index24 alt2"> ` ``super``.onScrollChanged(l, t, oldl, oldt);` </div> <div class="line number26 index25 alt1"> </div> <div class="line number27 index26 alt2"> ` ``mScrollInterface.onSChanged(l, t, oldl, oldt);` </div> <div class="line number28 index27 alt1"> </div> <div class="line number29 index28 alt2"> ` ``}` </div> <div class="line number30 index29 alt1"> </div> <div class="line number31 index30 alt2"> ` ``public` `void` `setOnCustomScroolChangeListener(ScrollInterface scrollInterface) {` </div> <div class="line number32 index31 alt1"> </div> <div class="line number33 index32 alt2"> ` ``this``.mScrollInterface = scrollInterface;` </div> <div class="line number34 index33 alt1"> </div> <div class="line number35 index34 alt2"> ` ``}` </div> <div class="line number36 index35 alt1"> </div> <div class="line number37 index36 alt2"> ` ``public` `interface` `ScrollInterface {` </div> <div class="line number38 index37 alt1"> </div> <div class="line number39 index38 alt2"> ` ``public` `void` `onSChanged(``int` `l, ``int` `t, ``int` `oldl, ``int` `oldt);` </div> <div class="line number40 index39 alt1"> </div> <div class="line number41 index40 alt2"> ` ``}` </div> <div class="line number42 index41 alt1"> </div> <div class="line number43 index42 alt2"> `}` </div> </div> </td> </tr> </table> </div> </div> &nbsp; main.xml如下: <div> <div id="highlighter_380669" class="syntaxhighlighter xml"> <div class="toolbar"> [?](http://www.open-open.com/lib/view/open1379383341959.html#) </div> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td class="gutter"> <div class="line number1 index0 alt2"> 1 </div> <div class="line number2 index1 alt1"> 2 </div> <div class="line number3 index2 alt2"> 3 </div> <div class="line number4 index3 alt1"> 4 </div> <div class="line number5 index4 alt2"> 5 </div> <div class="line number6 index5 alt1"> 6 </div> <div class="line number7 index6 alt2"> 7 </div> <div class="line number8 index7 alt1"> 8 </div> <div class="line number9 index8 alt2"> 9 </div> <div class="line number10 index9 alt1"> 10 </div> <div class="line number11 index10 alt2"> 11 </div> <div class="line number12 index11 alt1"> 12 </div> <div class="line number13 index12 alt2"> 13 </div> <div class="line number14 index13 alt1"> 14 </div> <div class="line number15 index14 alt2"> 15 </div> <div class="line number16 index15 alt1"> 16 </div> </td> <td class="code"> <div class="container"> <div class="line number1 index0 alt2"> `&lt;``RelativeLayout` </div> <div class="line number2 index1 alt1"> ` ``xmlns:android``=``"http://schemas.android.com/apk/res/android"` </div> <div class="line number3 index2 alt2"> ` ``xmlns:tools``=``"http://schemas.android.com/tools"` </div> <div class="line number4 index3 alt1"> ` ``android:layout_width``=``"match_parent"` </div> <div class="line number5 index4 alt2"> ` ``android:layout_height``=``"match_parent"` </div> <div class="line number6 index5 alt1"> ` ``&gt;` </div> <div class="line number7 index6 alt2"> </div> <div class="line number8 index7 alt1"> ` ``&lt;``cn.testwebview.TestWebView` </div> <div class="line number9 index8 alt2"> ` ``android:id``=``"@+id/webView"` </div> <div class="line number10 index9 alt1"> ` ``android:layout_width``=``"fill_parent"` </div> <div class="line number11 index10 alt2"> ` ``android:layout_height``=``"fill_parent"` </div> <div class="line number12 index11 alt1"> ` ``android:text``=``"@string/hello_world"` </div> <div class="line number13 index12 alt2"> ` ``android:layout_centerInParent``=``"true"` </div> <div class="line number14 index13 alt1"> ` ``/&gt;` </div> <div class="line number15 index14 alt2"> </div> <div class="line number16 index15 alt1"> `&lt;/``RelativeLayout``&gt;` </div> </div> </td> </tr> </table> </div> </div> &nbsp; </div>

2015年5月25日 · 13 分钟 · 天边的星星

Android大图片裁剪终极解决方案(上:原理分析)

约几个月前,我正为公司的APP在Android手机上实现拍照截图而烦恼不已。 上网搜索,确实有不少的例子,大多都是抄来抄去,而且水平多半处于demo的样子,可以用来讲解知识点,但是一碰到实际项目,就漏洞百出。 当时我用大众化的解决方案,暂时性的做了一个拍照截图的功能,似乎看起来很不错。问题随之而来,我用的是小米手机,在别的手机上都运行正常,小米这里却总是碰钉子。虽然我是个理性的米粉,但是也暗地里把小米的工程师问候了个遍。真是惭愧! 翻文档也找不出个答案来,我一直对com.android.camera.action.CROP持有大大的疑问,它是从哪里来,它能干什么,它接收处理什么类型的数据?Google对此却讳莫如深,在官方文档中只有Intent中有只言片语言及,却不甚详尽。 随着项目的驱动,我不能抱着不了解原理就不往前走的心态,唯一要做的,是解决问题。最后在德问上找到一条解决方案,说是哪怕是大米也没问题。当时乐呵呵将代码改了改,确实在所有的手机上跑起来了,一时如释重负,对这个的疑问也抛诸脑后了。 直到月前,BOSS要求将拍照上传到服务器的图片分辨率加倍。OK,加倍简单,增加outputX以及outputY不就得了? `1` <td class="content"> `intent.putExtra(``"outputX"``, outputX);` </td> </tr> </table> </div> <div class="line alt2"> <table> <tr> <td class="number"> `2` </td> <td class="content"> `intent.putExtra(``"outputY"``, outputY);` </td> </tr> </table> </div> 这一增加,吓了我一跳。BOSS的手机拍到的照片几乎就是个缩略图,但是被我问候了全体工程师的小米在这个时候就体现出国产神机的范儿了,小米上的尺寸一切正常。这个为什么呢?我大致了解原因,却不知道如何解决。 在Android中,Intent触发Camera程序,拍好照片后,将会返回数据,但是考虑到内存问题,Camera不会将全尺寸的图像返回给调用的Activity,一般情况下,有可能返回的是缩略图,比如120*160px。 这是为什么呢?这不是一个Bug,而是经过精心设计的,却对开发者不透明。 以我的小米手机为例,摄像头800W像素,根据我目前设置拍出来的图片尺寸为3200*2400px。有人说,那就返回呗,大不了耗1-2M的内存,不错,这个尺寸的图片确实只有1.8M左右的大小。但是你想不到的是,这个尺寸对应的Bitmap会耗光你应用程序的所有内存。Android出于安全性考虑,只会给你一个寒碜的缩略图。 在Android2.3中,默认的Bitmap为32位,类型是ARGB_8888,也就意味着一个像素点占用4个字节的内存。我们来做一个简单的计算题:3200*2400*4 bytes = 30M。 如此惊人的数字!哪怕你愿意为一张生命周期超不过10s的位图愿意耗费这么巨大的内存,Android也不会答应的。 `1` <td class="content"> `Mobile devices typically have constrained system resources.` </td> </tr> </table> </div> <div class="line alt2"> <table> <tr> <td class="number"> `2` </td> <td class="content"> `Android devices can have as little as 16MB of memory available to a single application.` </td> </tr> </table> </div> 这是Android Doc的原文,虽然不同手机系统的厂商可能围绕16M这个数字有微微的上调,但是这30M,一般的手机还真挥霍不起。也只有小米这种牛机,内存堪比个人PC,本着土财主般挥金如土的霸气才能做到。 ...

2015年5月23日 · 10 分钟 · 天边的星星

GitHub控件之BadgeView(数字提醒)

数字提醒大家肯定都见识过。QQ、微信等app中如果有消息或者提醒的时候,就会展现给用户一个红点或者带有数字的点。前段时间微信上流行把自己的头像换成带有数字提醒的头像,让那些有强迫症的人真是抓狂。 下面我们就看一下怎么在自己的app中实现这种效果。 开发者当然可以自己用相对布局来实现这样的效果。一个还好,但是多了呢!就会很繁琐。GitHub上有一个开源的第三方控件,叫做BadgeView。使用它可以很方面的实现想要的效果。 先来怎么使用,简单的三行代码就可以实现数字提醒: **[java]** [view plain](http://blog.csdn.net/crazy1235/article/details/42262369#)[copy](http://blog.csdn.net/crazy1235/article/details/42262369#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/571341)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/571341/fork) <div> <embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_1"> </embed> </div> </div> - BadgeView badgeView = <span class="keyword">new</span> com.jauker.widget.BadgeView(<span class="keyword">this</span>); - badgeView.setTargetView(textView); - badgeView.setBadgeCount(<span class="number">3</span>); 看一下badgeview中常用的方法: **[java]** [view plain](http://blog.csdn.net/crazy1235/article/details/42262369#)[copy](http://blog.csdn.net/crazy1235/article/details/42262369#)[![在CODE上查看代码片](https://code.csdn.net/assets/CODE_ico.png)](https://code.csdn.net/snippets/571341)[![派生到我的代码片](https://code.csdn.net/assets/ico_fork.svg)](https://code.csdn.net/snippets/571341/fork) <div> <embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" type="application/x-shockwave-flash" width="18" height="18" align="middle" name="ZeroClipboardMovie_2"> </embed> </div> </div> - badgeView = <span class="keyword">new</span> BadgeView(<span class="keyword">this</span>); - badgeView.setTargetView(layout); - badgeView.setBackground(<span class="number">12</span>, Color.parseColor(<span class="string">&#8220;#9b2eef&#8221;</span>)); - badgeView.setText(<span class="string">&#8220;提示&#8221;</span>); ...

2015年5月21日 · 1 分钟 · 天边的星星

Android消息推送完美解决方案全析

推送功能在手机应用开发中越来越重要,已经成为手机开发的必须。在Android应用开发中,由于众所周知的原因,Android消息推送我们不得不大费周折。本文就是用来和大家共同探讨一种Android消息推送的完美解决方案。 一、消息推送基础 消息推送,就是在互联网上通过定期传送用户需要的信息来减少信息过载的一项新技术。推送技术通过自动传送信息给用户,来减少用于网络上搜索的时间。它根据用户的兴趣来搜索、过滤信息,并将其定期推给用户,帮助用户高效率地发掘有价值的信息 当我们开发需要和服务器交互的移动应用时,基本上都需要和服务器进行交互,包括上传数据到服务器,同时从服务器上获取数据。 一般情况下,客户端与服务器之间通讯客户端是主动的,但这就存在一个问题就是一旦服务器数据有更新或者服务器要下发通知给客户端只能等客户端连接的时候才能实现。这种方式使消息失去了实时性。 如何使客户端能够实时的收到服务器的消息和通知,总体来说有两种方式,第一种是客户端使用Pull(拉)的方式,就是隔一段时间就去服务器上获取一下信息,看是否有更新的信息出现。第二种就是 服务器使用Push(推送)的方式,当服务器端有新信息了,则把最新的信息Push到客户端上。这样,客户端就能自动的接收到消息。 虽然Pull和Push两种方式都能实现获取服务器端更新信息的功能,但是明显来说Push方式比Pull方式更优越。因为Pull方式更费客户端的网络流量,更主要的是费电量,还需要我们的程序不停地去监测服务端的变化。 二、几种常见的解决方案实现原理 1)轮询(Pull)方式:客户端定时向服务器发送询问消息,一旦服务器有变化则立即同步消息。 2)SMS(Push)方式:通过拦截SMS消息并且解析消息内容来了解服务器的命令,但这种方式一般用户在经济上很难承受。 3)持久连接(Push)方式:客户端和服务器之间建立长久连接,这样就可以实现消息的及时行和实时性。 三、消息推送解决方案概述 A、C2DM云端推送方案 在Android手机平台上,Google提供了C2DM(Cloudto Device Messaging)服务。Android Cloud to Device Messaging (C2DM)是一个用来帮助开发者从服务器向Android应用程序发送数据的服务。该服务提供了一个简单的、轻量级的机制,允许服务器可以通知移动应用程序直接与服务器进行通信,以便于从服务器获取应用程序更新和用户数据。 该方案存在的主要问题是C2DM需要依赖于Google官方提供的C2DM服务器,由于国内的网络环境,这个服务经常不可用。 B、MQTT协议实现Android推送 采用MQTT协议实现Android推送功能也是一种解决方案。MQTT是一个轻量级的消息发布/订阅协议,它是实现基于手机客户端的消息推送服务器的理想解决方案。 wmqtt.jar 是IBM提供的MQTT协议的实现。我们可以从这里(https://github.com/tokudu/AndroidPushNotificationsDemo)下载该项目的实例代码,并且可以找到一个采用PHP书写的服务器端实现(https://github.com/tokudu/PhpMQTTClient)。 C、RSMB实现推送功能 Really Small Message Broker (RSMB) ,是一个简单的MQTT代理,同样由IBM提供,其查看地址是:http://www.alphaworks.ibm.com/tech/rsmb。缺省打开1883端口,应用程序当中,它负责接收来自服务器的消息并将其转发给指定的移动设备。SAM是一个针对MQTT写的PHP库。我们可以从这个http://pecl.php.net/package/sam/download/0.2.0地址下载它. D、XMPP协议实现Android推送 Google官方的C2DM服务器底层也是采用XMPP协议进行的封装。XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。 androidpn是一个基于XMPP协议的java开源Android push notification实现。它包含了完整的客户端和服务器端。但也存在一些不足之处: 1) 比如时间过长时,就再也收不到推送的信息了。 2)性能上也不够稳定。 3)如果将消息从服务器上推送出去,就不再管理了,不管消息是否成功到达客户端手机上。 如果我们要使用androidpn,则还需要做大量的工作,需要理解XMPP协议、理解Androidpn的实现机制,需要调试内部存在的BUG。 E、使用第三方平台 目前国内、国外有一些推送平台可供使用,但是涉及到收费问题、保密问题、服务质量问题、扩展问题等等,又不得不是我们望而却步。 四、消息推送完美方案 综合以上论述,在建立Android消息推送方面可谓方案多多,但每一款方案都有其优缺点。但无论如何,还是自己搭建一个推送平台是上策。因为你有、他有不如自己有。 举个例子,在搭建自有推送平台上建议使用《某某Android消息推送组件》。该组不仅可以拿来即用,并且还可以提供源码以便扩展,实现自己的特殊需求。 A、推送原理 Android消息推送组件基于XMPP协议实现Android推送。XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。 Android消息推送组件实现原理见下图: 图1-消息推送原理图 Android消息推送组件由服务器部分和客户端部分组成。每一部分都由XMPP协议组件和外部接口组件构成。XMPP协议组件负责服务器和Android客户端间的连接管理、消息通讯,外部接口组件负责接收应用系统、客户端应用的命令,向应用系统发送接收到的通知消息。 Android消息组件提供基于Tomcat的服务器应用和Android开发jar包。其中基于Tomcat的服务器应用直接在Tomcat上部署即可,Android开发jar包引入Android项目即可。 B 集成方式 1)服务器部署 Android消息组件Tomcat的服务器应用直接部署在Tomcat中,端口号任意设定。 2)客户端jar包引用 在Android项目中建立libs目录,然后将提供的Android开发jar包复制到该目录即可。见下图: 图2-jar包引入图 3)Android项目AndroidManifest.xml文件修改 在该文件中增加以下权限: <uses-permission android:name=“android.permission.READ_PHONE_STATE” /> <uses-permission android:name=“android.permission.ACCESS_NETWORK_STATE” /> ...

2015年5月21日 · 1 分钟 · 天边的星星

Android RecyclerView 使用完全解析 体验艺术般的控件

概述 RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用。 据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件我们并不陌生,例如:ListView、GridView。 那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。 你想要控制其显示的方式,请通过布局管理器LayoutManager 你想要控制Item间的间隔(可绘制),请通过ItemDecoration 你想要控制Item增删的动画,请通过ItemAnimator 你想要控制点击、长按事件,请自己写(擦,这点尼玛。) 基本使用 鉴于我们对于ListView的使用特别的熟悉,对比下RecyclerView的使用代码: `mRecyclerView = findView(R.id.id_recyclerview); &lt;span class="hljs-comment">//设置布局管理器&lt;/span> mRecyclerView.setLayoutManager(layout); &lt;span class="hljs-comment">//设置adapter&lt;/span> mRecyclerView.setAdapter(adapter) &lt;span class="hljs-comment">//设置Item增加、移除动画&lt;/span> mRecyclerView.setItemAnimator(&lt;span class="hljs-keyword">new&lt;/span> DefaultItemAnimator()); &lt;span class="hljs-comment">//添加分割线&lt;/span> mRecyclerView.addItemDecoration(&lt;span class="hljs-keyword">new&lt;/span> DividerItemDecoration( getActivity(), DividerItemDecoration.HORIZONTAL_LIST));` ok,相比较于ListView的代码,ListView可能只需要去设置一个adapter就能正常使用了。而RecyclerView基本需要上面一系列的步骤,那么为什么会添加这么多的步骤呢? 那么就必须解释下RecyclerView的这个名字了,从它类名上看,RecyclerView代表的意义是,我只管Recycler View,也就是说RecyclerView只管回收与复用View,其他的你可以自己去设置。可以看出其高度的解耦,给予你充分的定制自由(所以你才可以轻松的通过这个控件实现ListView,GirdView,瀑布流等效果)。 Just like ListView Activity `&lt;span class="hljs-keyword">package&lt;/span> com.zhy.sample.demo_recyclerview; &lt;span class="hljs-keyword">import&lt;/span> java.util.ArrayList; &lt;span class="hljs-keyword">import&lt;/span> java.util.List; &lt;span class="hljs-keyword">import&lt;/span> android.os.Bundle; &lt;span class="hljs-keyword">import&lt;/span> android.support.v7.app.ActionBarActivity; &lt;span class="hljs-keyword">import&lt;/span> android.support.v7.widget.LinearLayoutManager; &lt;span class="hljs-keyword">import&lt;/span> android.support.v7.widget.RecyclerView; &lt;span class="hljs-keyword">import&lt;/span> android.support.v7.widget.RecyclerView.ViewHolder; &lt;span class="hljs-keyword">import&lt;/span> android.view.LayoutInflater; &lt;span class="hljs-keyword">import&lt;/span> android.view.View; &lt;span class="hljs-keyword">import&lt;/span> android.view.ViewGroup; &lt;span class="hljs-keyword">import&lt;/span> android.widget.TextView; &lt;span class="hljs-keyword">public&lt;/span> &lt;span class="hljs-class">&lt;span class="hljs-keyword">class&lt;/span> &lt;span class="hljs-title">HomeActivity&lt;/span> &lt;span class="hljs-keyword">extends&lt;/span> &lt;span class="hljs-title">ActionBarActivity&lt;/span> {&lt;/span> &lt;span class="hljs-keyword">private&lt;/span> RecyclerView mRecyclerView; &lt;span class="hljs-keyword">private&lt;/span> List&lt;String&gt; mDatas; &lt;span class="hljs-keyword">private&lt;/span> HomeAdapter mAdapter; &lt;span class="hljs-annotation">@Override&lt;/span> &lt;span class="hljs-keyword">protected&lt;/span> &lt;span class="hljs-keyword">void&lt;/span> &lt;span class="hljs-title">onCreate&lt;/span>(Bundle savedInstanceState) { &lt;span class="hljs-keyword">super&lt;/span>.onCreate(savedInstanceState); setContentView(R.layout.activity_single_recyclerview); initData(); mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview); mRecyclerView.setLayoutManager(&lt;span class="hljs-keyword">new&lt;/span> LinearLayoutManager(&lt;span class="hljs-keyword">this&lt;/span>)); mRecyclerView.setAdapter(mAdapter = &lt;span class="hljs-keyword">new&lt;/span> HomeAdapter()); } &lt;span class="hljs-keyword">protected&lt;/span> &lt;span class="hljs-keyword">void&lt;/span> &lt;span class="hljs-title">initData&lt;/span>() { mDatas = &lt;span class="hljs-keyword">new&lt;/span> ArrayList&lt;String&gt;(); &lt;span class="hljs-keyword">for&lt;/span> (&lt;span class="hljs-keyword">int&lt;/span> i = &lt;span class="hljs-string">'A'&lt;/span>; i &lt; &lt;span class="hljs-string">'z'&lt;/span>; i++) { mDatas.add(&lt;span class="hljs-string">""&lt;/span> + (&lt;span class="hljs-keyword">char&lt;/span>) i); } } class HomeAdapter extends RecyclerView.Adapter&lt;HomeAdapter.MyViewHolder&gt; { &lt;span class="hljs-annotation">@Override&lt;/span> &lt;span class="hljs-keyword">public&lt;/span> MyViewHolder &lt;span class="hljs-title">onCreateViewHolder&lt;/span>(ViewGroup parent, &lt;span class="hljs-keyword">int&lt;/span> viewType) { MyViewHolder holder = &lt;span class="hljs-keyword">new&lt;/span> MyViewHolder(LayoutInflater.from( HomeActivity.&lt;span class="hljs-keyword">this&lt;/span>).inflate(R.layout.item_home, parent, &lt;span class="hljs-keyword">false&lt;/span>)); &lt;span class="hljs-keyword">return&lt;/span> holder; } &lt;span class="hljs-annotation">@Override&lt;/span> &lt;span class="hljs-keyword">public&lt;/span> &lt;span class="hljs-keyword">void&lt;/span> &lt;span class="hljs-title">onBindViewHolder&lt;/span>(MyViewHolder holder, &lt;span class="hljs-keyword">int&lt;/span> position) { holder.tv.setText(mDatas.get(position)); } &lt;span class="hljs-annotation">@Override&lt;/span> &lt;span class="hljs-keyword">public&lt;/span> &lt;span class="hljs-keyword">int&lt;/span> &lt;span class="hljs-title">getItemCount&lt;/span>() { &lt;span class="hljs-keyword">return&lt;/span> mDatas.size(); } class MyViewHolder extends ViewHolder { TextView tv; &lt;span class="hljs-keyword">public&lt;/span> &lt;span class="hljs-title">MyViewHolder&lt;/span>(View view) { &lt;span class="hljs-keyword">super&lt;/span>(view); tv = (TextView) view.findViewById(R.id.id_num); } } } }` Activity的布局文件 `&lt;span class="hljs-tag">&lt;&lt;span class="hljs-title">RelativeLayout&lt;/span> &lt;span class="hljs-attribute">xmlns:android&lt;/span>=&lt;span class="hljs-value">"http://schemas.android.com/apk/res/android"&lt;/span> &lt;span class="hljs-attribute">xmlns:tools&lt;/span>=&lt;span class="hljs-value">"http://schemas.android.com/tools"&lt;/span> &lt;span class="hljs-attribute">android:layout_width&lt;/span>=&lt;span class="hljs-value">"match_parent"&lt;/span> &lt;span class="hljs-attribute">android:layout_height&lt;/span>=&lt;span class="hljs-value">"match_parent"&lt;/span> &gt;&lt;/span> &lt;span class="hljs-tag">&lt;&lt;span class="hljs-title">android.support.v7.widget.RecyclerView &lt;/span> &lt;span class="hljs-attribute">android:id&lt;/span>=&lt;span class="hljs-value">"@+id/id_recyclerview"&lt;/span> &lt;span class="hljs-attribute">android:divider&lt;/span>=&lt;span class="hljs-value">"#ffff0000"&lt;/span> &lt;span class="hljs-attribute">android:dividerHeight&lt;/span>=&lt;span class="hljs-value">"10dp"&lt;/span> &lt;span class="hljs-attribute">android:layout_width&lt;/span>=&lt;span class="hljs-value">"match_parent"&lt;/span> &lt;span class="hljs-attribute">android:layout_height&lt;/span>=&lt;span class="hljs-value">"match_parent"&lt;/span> /&gt;&lt;/span> &lt;span class="hljs-tag">&lt;/&lt;span class="hljs-title">RelativeLayout&lt;/span>&gt;&lt;/span>` Item的布局文件 `&lt;span class="hljs-pi">&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;/span> &lt;span class="hljs-tag">&lt;&lt;span class="hljs-title">FrameLayout&lt;/span> &lt;span class="hljs-attribute">xmlns:android&lt;/span>=&lt;span class="hljs-value">"http://schemas.android.com/apk/res/android"&lt;/span> &lt;span class="hljs-attribute">android:layout_width&lt;/span>=&lt;span class="hljs-value">"match_parent"&lt;/span> &lt;span class="hljs-attribute">android:background&lt;/span>=&lt;span class="hljs-value">"#44ff0000"&lt;/span> &lt;span class="hljs-attribute">android:layout_height&lt;/span>=&lt;span class="hljs-value">"wrap_content"&lt;/span> &gt;&lt;/span> &lt;span class="hljs-tag">&lt;&lt;span class="hljs-title">TextView &lt;/span> &lt;span class="hljs-attribute">android:id&lt;/span>=&lt;span class="hljs-value">"@+id/id_num"&lt;/span> &lt;span class="hljs-attribute">android:layout_width&lt;/span>=&lt;span class="hljs-value">"match_parent"&lt;/span> &lt;span class="hljs-attribute">android:layout_height&lt;/span>=&lt;span class="hljs-value">"50dp"&lt;/span> &lt;span class="hljs-attribute">android:gravity&lt;/span>=&lt;span class="hljs-value">"center"&lt;/span> &lt;span class="hljs-attribute">android:text&lt;/span>=&lt;span class="hljs-value">"1"&lt;/span> /&gt;&lt;/span> &lt;span class="hljs-tag">&lt;/&lt;span class="hljs-title">FrameLayout&lt;/span>&gt;&lt;/span>` 这么看起来用法与ListView的代码基本一致哈~~ 看下效果图: ...

2015年5月19日 · 10 分钟 · 天边的星星

设置Viewpager的viewPager.setCurrentItem有一个动画滑动效果

设置Viewpager的viewPager.setCurrentItem(currentIndex+1);有一个动画滑动效果 ViewPagerScroller scroller = new ViewPagerScroller(this); scroller.initViewPagerScroll(viewPager); /** ViewPager 滚动速度设置 */ public class ViewPagerScroller extends Scroller { private int mScrollDuration = 2000; // 滑动速度 /** 设置速度速度 @param duration */ public void setScrollDuration(int duration) { this.mScrollDuration = duration; } public ViewPagerScroller(Context context) { super(context); } public ViewPagerScroller(Context context, Interpolator interpolator) { super(context, interpolator); } @SuppressLint(“NewApi”) public ViewPagerScroller(Context context, Interpolator interpolator, boolean flywheel) { super(context, interpolator, flywheel); } @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { super.startScroll(startX, startY, dx, dy, mScrollDuration); } ...

2015年5月8日 · 1 分钟 · 天边的星星

Android — RecyclerView

“A flexible view for providing a limited window into a large data set.” 可以说是ListView的升级版,ListVie中我们需要自己写ViewHolder,当然你也可以不写,是在RecylerView中,是要让写的哟~RecyclerView适用于无法在一个屏幕范围内展现格式一样的数据时,需要用多行或多列来展示。例如展示联系人,图片,视频等。用户需要滑动屏幕来查看数据,这时RecyclerView的特性就有用武之地了。比如,当用户滑动使当前一个可视的Item滑出屏幕,这个Item的视图将会被回收并在一个新Item进入可视范围后重新被使用。可回收利用View是个很实用的功能,它不仅可以减少CPU不断inflate View的开销,而且可以节省缓存View的内存开销。 RecylerView还有一大特色,就是动画! RecyclerView不再负责显示工作 和ListView不一样的是,RecyclerView不再负责Item的摆放等显示方面的功能。所有和布局、绘制等方面的工作都其拆分成不同的类进行管理。所以开发者可以自定义各种各样满足定制需求的的功能类。 RecyclerView.Adapter <td valign="top" width="454"> 托管数据集合,为每个Item创建视图 </td> </tr> <tr> <td valign="top" width="326"> RecyclerView.ViewHolder </td> <td valign="top" width="454"> 承载Item视图的子视图 </td> </tr> <tr> <td valign="top" width="326"> RecyclerView.LayoutManager </td> <td valign="top" width="454"> 负责Item视图的布局 </td> </tr> <tr> <td valign="top" width="326"> RecyclerView.ItemDecoration </td> <td valign="top" width="454"> 为每个Item视图添加子视图,在Demo中被用来绘制Divider </td> </tr> <tr> <td valign="top" width="326"> RecyclerView.ItemAnimator </td> <td valign="top" width="454"> 负责添加、删除数据时的动画效果 </td> </tr> ViewHolder 关于ViewHolder,Google早就推荐开发者使用,但也只是建议。但是现在,RecyclerView.Adapter最终要求开发者必须使用ViewHolder。 ...

2015年5月8日 · 3 分钟 · 天边的星星

【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法…

[http://blog.csdn.net/shulianghan/article/details/41520569](http://blog.csdn.net/shulianghan/article/details/41520569?utm_source=tuicool) **博客地址 **: [http://blog.csdn.net/shulianghan/article/details/41520569](http://blog.csdn.net/shulianghan/article/details/41520569) 代码下载 : &#8212; **GitHub **: [https://github.com/han1202012/WheelViewDemo.git](https://github.com/han1202012/WheelViewDemo.git) &#8212; **CSDN **: [http://download.csdn.net/detail/han1202012/8208997](http://download.csdn.net/detail/han1202012/8208997) ; #### 博客总结 : 博文内容 : 本文完整地分析了 WheelView 所有的源码, 包括其 适配器类型 , 两种回调接口 ( 选中条目改变回调 , 和 开始结束滚动回调 ), 以及详细的分析了 WheelView 主题源码, 其中 组件宽高测量 , 手势监听器添加 , 以及 精准的绘图方法 是主要目的, 花了将近1周时间, 感觉很值, 在这里分享给大家; 自定义组件宽高获取策略 : MeasureSpec 最大模式 取 默认值 和 给定值中较小的那个 , 未定义模式取默认值 , 精准模式取 给定值 ; 自定义组件维护各种回调监听器策略 : 维护集合, 将监听器置于集合中, 回调接口时遍历集合元素, 回调每个元素的接口方法; 自定义组件手势监听器添加方法 : 创建手势监听器, 将手势监听器传入手势探测器, 在 onTouchEvent() 方法中回调手势监听器的 onTouchEvent()方法; ## 一. WheelView 简介 ## 1. WheelView 效果 在 Android 中实现类似与 IOS 的 WheelView 控件 : 如图 ![](http://img2.tuicool.com/bMfU7b.png) ## 2. WheelView 使用流程 ### (1) 基本流程简介 a. 创建 WheelView 组件 : 使用 构造方法 或者 从布局文件获取 WheelView 组件; b. 设置显示条目数 : 调用 WheelView 组件对象的 setVisibleItems 方法 设置; c. 设置是否循环 : 设置 WheelView 是否循环, 调用 setCyclic() 方法设置; d. 设置适配器 : 调用 WheelView 组件的 setAdapter() 方法设置; e. 设置条目改变监听器 : 调用 WheelView 组件对象的 addChangingListener() 方法设置; f. 设置滚动监听器 : 调用 WheelView 组件对象的 addScrollingListener() 方法设置; ### (2) 代码实例 a. 创建 WheelView 对象 : ``` //创建 WheelView 组件 final WheelView wheelLeft = new WheelView(context); ...

2015年5月7日 · 47 分钟 · 天边的星星