在Android本地视频播放器开发--搜索本地视频(1)中我们获取了本地视频的数据,在这一章里面,我们将获取的数据通过LIstView来动态的实现出来。
1、首先介绍布局代码,主布局代码只含有一个LIstView --jie_video.xml
<?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的子项的布局
<?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
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
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的类,它的代码如下:
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; } }
那就看看最终的实现效果吧: