編輯:關於Android編程
1、首先介紹布局代碼,主布局代碼只含有一個LIstView --jie_video.xml
[html]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:id="@+id/jievideolistfile"
/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:id="@+id/jievideolistfile"
/>
</RelativeLayout>2、下一個布局就是listView的子項的布局
[html]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="120dp"
android:layout_height="80dp"
android:id="@+id/video_img"
android:contentDescription="@string/cont"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/video_img"
android:layout_alignBottom="@id/video_img"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/video_title"
android:gravity="center"
android:layout_marginTop="5dp"
android:text="@string/title"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/video_time"
android:gravity="center"
android:layout_alignParentBottom="true"
android:layout_marginBottom="5dp"
android:text="@string/time"
/>
</RelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="120dp"
android:layout_height="80dp"
android:id="@+id/video_img"
android:contentDescription="@string/cont"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/video_img"
android:layout_alignBottom="@id/video_img"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/video_title"
android:gravity="center"
android:layout_marginTop="5dp"
android:text="@string/title"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/video_time"
android:gravity="center"
android:layout_alignParentBottom="true"
android:layout_marginBottom="5dp"
android:text="@string/time"
/>
</RelativeLayout>
</RelativeLayout>
3、布局都寫好了,然後就是Activity的編寫,這裡涉及到視頻的縮略圖的顯示,所以要用到異步加載功能
JieVideo.java
[java]
package com.zhangjie.graduation.videopalyer;
import java.util.List;
import com.zhangjie.graduation.videopalyer.component.JieVideoListViewAdapter;
import com.zhangjie.graduation.videopalyer.component.LoadedImage;
import com.zhangjie.graduation.videopalyer.videofile.AbstructProvider;
import com.zhangjie.graduation.videopalyer.videofile.Video;
import com.zhangjie.graduation.videopalyer.videofile.VideoProvider;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore.Video.Thumbnails;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
public class JieVideo extends Activity{
public JieVideo instance = null;
ListView mJieVideoListView;
JieVideoListViewAdapter mJieVideoListViewAdapter;
List<Video> listVideos;
int videoSize;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.jie_video);
instance = this;
AbstructProvider provider = new VideoProvider(instance);
listVideos = provider.getList();
videoSize = listVideos.size();
mJieVideoListViewAdapter = new JieVideoListViewAdapter(this, listVideos);
mJieVideoListView = (ListView)findViewById(R.id.jievideolistfile);
mJieVideoListView.setAdapter(mJieVideoListViewAdapter);
mJieVideoListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent intent = new Intent();
intent.setClass(JieVideo.this, JieVideoPlayer.class);
Bundle bundle = new Bundle();
bundle.putSerializable("video", listVideos.get(position));
intent.putExtras(bundle);
startActivity(intent);
}
});
loadImages();
}
/**
* Load images.
*/
private void loadImages() {
final Object data = getLastNonConfigurationInstance();
if (data == null) {
new LoadImagesFromSDCard().execute();
} else {
final LoadedImage[] photos = (LoadedImage[]) data;
if (photos.length == 0) {
new LoadImagesFromSDCard().execute();
}
for (LoadedImage photo : photos) {
addImage(photo);
}
}
}
private void addImage(LoadedImage... value) {
for (LoadedImage image : value) {
mJieVideoListViewAdapter.addPhoto(image);
mJieVideoListViewAdapter.notifyDataSetChanged();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
final ListView grid = mJieVideoListView;
final int count = grid.getChildCount();
final LoadedImage[] list = new LoadedImage[count];
for (int i = 0; i < count; i++) {
final ImageView v = (ImageView) grid.getChildAt(i);
list[i] = new LoadedImage(
((BitmapDrawable) v.getDrawable()).getBitmap());
}
return list;
}
/**
* 獲取視頻縮略圖
* @param videoPath
* @param width
* @param height
* @param kind
* @return
*/
private Bitmap getVideoThumbnail(String videoPath, int width , int height, int kind){
Bitmap bitmap = null;
bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
return bitmap;
}
class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {
@Override
protected Object doInBackground(Object... params) {
Bitmap bitmap = null;
for (int i = 0; i < videoSize; i++) {
bitmap = getVideoThumbnail(listVideos.get(i).getPath(), 120, 120, Thumbnails.MINI_KIND);
if (bitmap != null) {
publishProgress(new LoadedImage(bitmap));
}
}
return null;
}
@Override
public void onProgressUpdate(LoadedImage... value) {
addImage(value);
}
}
}
package com.zhangjie.graduation.videopalyer;
import java.util.List;
import com.zhangjie.graduation.videopalyer.component.JieVideoListViewAdapter;
import com.zhangjie.graduation.videopalyer.component.LoadedImage;
import com.zhangjie.graduation.videopalyer.videofile.AbstructProvider;
import com.zhangjie.graduation.videopalyer.videofile.Video;
import com.zhangjie.graduation.videopalyer.videofile.VideoProvider;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore.Video.Thumbnails;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
public class JieVideo extends Activity{
public JieVideo instance = null;
ListView mJieVideoListView;
JieVideoListViewAdapter mJieVideoListViewAdapter;
List<Video> listVideos;
int videoSize;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.jie_video);
instance = this;
AbstructProvider provider = new VideoProvider(instance);
listVideos = provider.getList();
videoSize = listVideos.size();
mJieVideoListViewAdapter = new JieVideoListViewAdapter(this, listVideos);
mJieVideoListView = (ListView)findViewById(R.id.jievideolistfile);
mJieVideoListView.setAdapter(mJieVideoListViewAdapter);
mJieVideoListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent intent = new Intent();
intent.setClass(JieVideo.this, JieVideoPlayer.class);
Bundle bundle = new Bundle();
bundle.putSerializable("video", listVideos.get(position));
intent.putExtras(bundle);
startActivity(intent);
}
});
loadImages();
}
/**
* Load images.
*/
private void loadImages() {
final Object data = getLastNonConfigurationInstance();
if (data == null) {
new LoadImagesFromSDCard().execute();
} else {
final LoadedImage[] photos = (LoadedImage[]) data;
if (photos.length == 0) {
new LoadImagesFromSDCard().execute();
}
for (LoadedImage photo : photos) {
addImage(photo);
}
}
}
private void addImage(LoadedImage... value) {
for (LoadedImage image : value) {
mJieVideoListViewAdapter.addPhoto(image);
mJieVideoListViewAdapter.notifyDataSetChanged();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
final ListView grid = mJieVideoListView;
final int count = grid.getChildCount();
final LoadedImage[] list = new LoadedImage[count];
for (int i = 0; i < count; i++) {
final ImageView v = (ImageView) grid.getChildAt(i);
list[i] = new LoadedImage(
((BitmapDrawable) v.getDrawable()).getBitmap());
}
return list;
}
/**
* 獲取視頻縮略圖
* @param videoPath
* @param width
* @param height
* @param kind
* @return
*/
private Bitmap getVideoThumbnail(String videoPath, int width , int height, int kind){
Bitmap bitmap = null;
bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
return bitmap;
}
class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {
@Override
protected Object doInBackground(Object... params) {
Bitmap bitmap = null;
for (int i = 0; i < videoSize; i++) {
bitmap = getVideoThumbnail(listVideos.get(i).getPath(), 120, 120, Thumbnails.MINI_KIND);
if (bitmap != null) {
publishProgress(new LoadedImage(bitmap));
}
}
return null;
}
@Override
public void onProgressUpdate(LoadedImage... value) {
addImage(value);
}
}
}
4、上面還涉及一個就是LIstView的適配器,這裡是繼承BaseAdapter。
JieVideoListViewAdapter.java
[java]
package com.zhangjie.graduation.videopalyer.component;
import java.util.ArrayList;
import java.util.List;
import com.zhangjie.graduation.videopalyer.R;
import com.zhangjie.graduation.videopalyer.videofile.Video;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class JieVideoListViewAdapter extends BaseAdapter{
List<Video> listVideos;
int local_postion = 0;
boolean imageChage = false;
private LayoutInflater mLayoutInflater;
private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();
public JieVideoListViewAdapter(Context context, List<Video> listVideos){
mLayoutInflater = LayoutInflater.from(context);
this.listVideos = listVideos;
}
@Override
public int getCount() {
return photos.size();
}
public void addPhoto(LoadedImage image){
photos.add(image);
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = mLayoutInflater.inflate(R.layout.video_list_view, null);
holder.img = (ImageView)convertView.findViewById(R.id.video_img);
holder.title = (TextView)convertView.findViewById(R.id.video_title);
holder.time = (TextView)convertView.findViewById(R.id.video_time);
convertView.setTag(holder);
}else {
holder = (ViewHolder)convertView.getTag();
}
holder.title.setText(listVideos.get(position).getTitle());//ms
long min = listVideos.get(position).getDuration() /1000 / 60;
long sec = listVideos.get(position).getDuration() /1000 % 60;
holder.time.setText(min+" : "+sec);
holder.img.setImageBitmap(photos.get(position).getBitmap());
return convertView;
}
public final class ViewHolder{
public ImageView img;
public TextView title;
public TextView time;
}
}
package com.zhangjie.graduation.videopalyer.component;
import java.util.ArrayList;
import java.util.List;
import com.zhangjie.graduation.videopalyer.R;
import com.zhangjie.graduation.videopalyer.videofile.Video;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class JieVideoListViewAdapter extends BaseAdapter{
List<Video> listVideos;
int local_postion = 0;
boolean imageChage = false;
private LayoutInflater mLayoutInflater;
private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();
public JieVideoListViewAdapter(Context context, List<Video> listVideos){
mLayoutInflater = LayoutInflater.from(context);
this.listVideos = listVideos;
}
@Override
public int getCount() {
return photos.size();
}
public void addPhoto(LoadedImage image){
photos.add(image);
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = mLayoutInflater.inflate(R.layout.video_list_view, null);
holder.img = (ImageView)convertView.findViewById(R.id.video_img);
holder.title = (TextView)convertView.findViewById(R.id.video_title);
holder.time = (TextView)convertView.findViewById(R.id.video_time);
convertView.setTag(holder);
}else {
holder = (ViewHolder)convertView.getTag();
}
holder.title.setText(listVideos.get(position).getTitle());//ms
long min = listVideos.get(position).getDuration() /1000 / 60;
long sec = listVideos.get(position).getDuration() /1000 % 60;
holder.time.setText(min+" : "+sec);
holder.img.setImageBitmap(photos.get(position).getBitmap());
return convertView;
}
public final class ViewHolder{
public ImageView img;
public TextView title;
public TextView time;
}
}
5、還有一個在JieVideo類中使用了一個LoadedImage的類,它的代碼如下:
[java]
package com.zhangjie.graduation.videopalyer.component;
import android.graphics.Bitmap;
public class LoadedImage {
Bitmap mBitmap;
public LoadedImage(Bitmap bitmap) {
mBitmap = bitmap;
}
public Bitmap getBitmap() {
return mBitmap;
}
}
package com.zhangjie.graduation.videopalyer.component;
import android.graphics.Bitmap;
public class LoadedImage {
Bitmap mBitmap;
public LoadedImage(Bitmap bitmap) {
mBitmap = bitmap;
}
public Bitmap getBitmap() {
return mBitmap;
}
}
那就看看最終的實現效果吧:
最近公司的軟件需要改國際版,需要Facebook和Twitter的登錄和分享。本人先用Umeng的第三方社會化分享實現了該功能,但是後來一想問題來了,經過查證。Umeng
打印機其實和Android沒有什麼大的關系,和linux內核關聯才是比較強的。最近調試打印機,有那麼一點心得,一點一點記錄下來。 最終的結果是要在Andro
Bluestacks是一個可以讓Android應用程序運行在電腦(現在包括windows系統,mac版)的一種模擬器,就是我們在電腦上也可以運行Androi
前言:加載並顯示gif是App常見的一個功能,像加載普通圖片一樣,大體應該包含以下幾項功能:1、自動下載GIF到本地文件作為緩存,第二次加載同一個url的圖片不需要下載第