打算记录一些自己在开发过程中遇到的一些技巧性代码,方便以后遇到相似功能时能够快速的找到,那就从这里开始吧。
1,如何截取当前屏幕(不包括当前Activity
的Title
)并分享:
a,获取当前Activity
的根视图:
1 View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
或者:
1 View rootView = findViewById(android.R.id.content);
或者:
1 View rootView = findViewById(android.R.id.content).getRootView();
关于android.R.id.content
,开发者文档中并没有给予说明,但经过测试它应该是用来获取setContentView()
中设置的View
。
b,截取当前根视图的屏幕:
1 public static Bitmap getScreenShot(View view) { 2 View screenView = view.getRootView(); 3 screenView.setDrawingCacheEnabled(true); 4 Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache()); 5 screenView.setDrawingCacheEnabled(false); 6 return bitmap; 7 }
getScreenShot
c,将当前屏幕的截屏保存至SDCard
:
1 private final static String dir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Screenshots"; 2 public static void store(Bitmap bm, String fileName){ 3 File dir = new File(dir); 4 if(!dir.exists()) 5 dir.mkdirs(); 6 File file = new File(dir, fileName); 7 try { 8 FileOutputStream fOut = new FileOutputStream(file); 9 bm.compress(Bitmap.CompressFormat.PNG, 85, fOut); 10 fOut.flush(); 11 fOut.close(); 12 } catch (Exception e) { 13 e.printStackTrace(); 14 } 15 }
store(Bitmap bm, String fileName)
d,最后将该图片文件分享出来:
1 private void shareImage(String file){ 2 Uri uri = Uri.fromFile(file); 3 Intent intent = new Intent(); 4 intent.setAction(Intent.ACTION_SEND); 5 intent.setType("image/*"); 6 intent.putExtra(android.content.Intent.EXTRA_SUBJECT, ""); 7 intent.putExtra(android.content.Intent.EXTRA_TEXT, ""); 8 intent.putExtra(Intent.EXTRA_STREAM, uri); 9 startActivity(Intent.createChooser(intent, "Share Screenshot")); 10 }
shareImage(String file)
2,如何对HTML5
中的视频截图:
a,初始化WebView
:
1 String webUrl = ...; 2 VideoView vv; 3 mWebView = (WebView) findViewById(R.id.webview); 4 mWebView.setWebChromeClient(chromeClient); 5 mWebView.setWebViewClient(wvClient); 6 mWebView.getSettings().setJavaScriptEnabled(true); 7 mWebView.getSettings().setPluginsEnabled(true); 8 mWebView.loadUrl(webUrl);
b,覆盖WebChromeClient
中的onShowCustomView
方法:
1 @Override 2 public void onShowCustomView(View view, CustomViewCallback callback) { 3 super.onShowCustomView(view, callback); 4 if (view instanceof FrameLayout){ 5 FrameLayout frame = (FrameLayout) view; 6 if (frame.getFocusedChild() instanceof VideoView){ 7 vv = (VideoView) frame.getFocusedChild(); 8 } 9 } 10 }
onShowCustomView(View view, CustomViewCallback callback)
c,截取VideoView
中播放的视频内容:
1 private Bitmap capture(VideoView vv){ 2 MediaMetadataRetriever rev = new MediaMetadataRetriever(); 3 rev.setDataSource(this, uri);//this is a Context; 4 Bitmap bitmap = rev.getFrameAtTime(vv.getCurrentPosition() * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); 5 return bitmap; 6 }
capture(VideoView vv)
d,如何还想将截屏幕保存或分享,请参见上面的代码示例.
3,如何动态获取保存在integer-array
中的动态资源id?
a,在res/values/
目录下创建arrays.xml
文件,创建内容如下:
1 <integer-array name="frag_home_ids"> 2 <item>@drawable/frag_home_credit_return_money</item> 3 <item>@drawable/frag_home_transfer</item> 4 <item>@drawable/frag_home_balance</item> 5 <item>@drawable/frag_home_charge</item> 6 <item>@drawable/frag_home_finance_cdd</item> 7 <item>@drawable/frag_home_finance_ybjr</item> 8 <item>@drawable/frag_home_more</item> 9 </integer-array>
arrays.xml
b,通过编码的方式获取integer-array
中的资源id整型值:
1 TypedArray tArray = getResources().obtainTypedArray(R.array.frag_home_ids); 2 int count = tArray.length(); 3 int[] ids = new int[count]; 4 for (int i = 0; i < ids.length; i++) { 5 ids[i] = tArray.getResourceId(i, 0); 6 }
c,使用已经获取到的资源的id:
1 holder.iv.setImageResource(ids[position]);
d,我们也还可以用这种方式获取string
, color
, integer
, layout
, menu
等的id
.
4,ListView
或GridView
局部刷新原理的实现:
1 private void refreshPartially(int position){ 2 int firstVisiblePosition = listview.getFirstVisiblePosition(); 3 int lastVisiblePosition = listview.getLastVisiblePosition(); 4 if(position>=firstVisiblePosition && position<=lastVisiblePosition){ 5 View view = listview.getChildAt(position - firstVisiblePosition); 6 if(view.getTag() instanceof ViewHolder){ 7 ViewHolder vh = (ViewHolder)view.getTag(); 8 //holder.play.setBackgroundResource(resId);//Do something here. 9 ... 10 } 11 } 12 }
refreshPartially(int position)
5,Google Volley
的单例模式实现:
1 package me.pc.mobile.tv.util; 2 3 import android.content.Context; 4 import android.graphics.Bitmap; 5 import android.util.LruCache; 6 import com.android.volley.RequestQueue; 7 import com.android.volley.toolbox.ImageLoader; 8 import com.android.volley.toolbox.Volley; 9 10 public class VolleySingleton { 11 private static VolleySingleton instance; 12 private RequestQueue requestQueue; 13 private ImageLoader imageLoader; 14 private VolleySingleton(Context context) { 15 requestQueue = Volley.newRequestQueue(context); 16 imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() { 17 private final LruCache<string, bitmap=""> cache = new LruCache<string, bitmap="">(20); 18 19 @Override 20 public Bitmap getBitmap(String url) { 21 return cache.get(url); 22 } 23 24 @Override 25 public void putBitmap(String url, Bitmap bitmap) { 26 cache.put(url, bitmap); 27 } 28 }); 29 } 30 31 public static VolleySingleton getInstance(Context context) { 32 if (instance == null) { 33 instance = new VolleySingleton(context); 34 } 35 return instance; 36 } 37 38 public RequestQueue getRequestQueue() { 39 return requestQueue; 40 } 41 42 public ImageLoader getImageLoader() { 43 return imageLoader; 44 } 45 }
VolleySingleton.java
采用Volley
的单例模式,就避免了在每一个Activity
或Frament
中都创建一个RequestQueue
的麻烦.
6,使用Google Volley
来实现文件的分块上传:
1 public class PhotoMultipartRequest extends Request { 2 3 private static final String FILE_PART_NAME = "file"; 4 5 private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create(); 6 private final Response.Listener mListener; 7 private final File mImageFile; 8 protected Map<string, string=""> headers; 9 10 public PhotoMultipartRequest(String url, ErrorListener errorListener, Listener listener, File imageFile){ 11 super(Method.POST, url, errorListener); 12 13 mListener = listener; 14 mImageFile = imageFile; 15 16 buildMultipartEntity(); 17 } 18 19 @Override 20 public Map<string, string=""> getHeaders() throws AuthFailureError { 21 Map<string, string=""> headers = super.getHeaders(); 22 23 if (headers == null || headers.equals(Collections.emptyMap())) { 24 headers = new HashMap<string, string="">(); 25 } 26 27 headers.put("Accept", "application/json"); 28 29 return headers; 30 } 31 32 private void buildMultipartEntity(){ 33 mBuilder.addBinaryBody(FILE_PART_NAME, mImageFile, ContentType.create("image/jpeg"), mImageFile.getName()); 34 mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); 35 mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8")); 36 } 37 38 @Override 39 public String getBodyContentType(){ 40 String contentTypeHeader = mBuilder.build().getContentType().getValue(); 41 return contentTypeHeader; 42 } 43 44 @Override 45 public byte[] getBody() throws AuthFailureError{ 46 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 47 try { 48 mBuilder.build().writeTo(bos); 49 } catch (IOException e) { 50 VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request."); 51 } 52 53 return bos.toByteArray(); 54 } 55 56 @Override 57 protected Response parseNetworkResponse(NetworkResponse response) { 58 T result = null; 59 return Response.success(result, HttpHeaderParser.parseCacheHeaders(response)); 60 } 61 62 @Override 63 protected void deliverResponse(T response) { 64 mListener.onResponse(response); 65 } 66 }
PhotoMultipartRequest.java
代码中使用了Apache
的httpclient.jar
文件,用于实现文件的拆分与上传.