Android 仿微信 图片选择器采用项目的框架上采用mvp模式,并用了我自己写的一套lib,地址ndileber
首先先定义了数据源,数据源可能来自于网络也可能来自于本地,于是我定义了两个数据源,分别处理网络和本地的数据:
我先创建了数据源接口:
ImageDataSource
public interface ImageDataSource extends BaseDataSource{
void getAllImage(BaseCallback<List<ImageModel>> callback);
}
建立model,model建立的原因是我要反向将数据注入到这里
public class ImageModel {
Integer _id;
String _display_name;
String _data;
private boolean check = false;
public boolean isCheck() {
return check;
}
public void setCheck(boolean check) {
this.check = check;
}
public Integer get_id() {
return _id;
}
public void set_id(Integer _id) {
this._id = _id;
}
public String get_display_name() {
return _display_name;
}
public void set_display_name(String _display_name) {
this._display_name = _display_name;
}
public String get_data() {
return _data;
}
public void set_data(String _data) {
this._data = _data;
}
}
网络数据源:当然目前仅仅是测试本地数据源,于是网络数据源只是简单的实现了ImageDataSource 方法
ImageRemoteDataSource
public class ImageRemoteDataSource extends BaseRemoteDataSource implements ImageDataSource {
private static volatile ImageRemoteDataSource instance;
private ImageRemoteDataSource(){
}
public static ImageRemoteDataSource getInstance(){
if (instance==null){
synchronized (ImageRemoteDataSource.class){
if(instance==null){
instance = new ImageRemoteDataSource();
}
}
}
return instance;
}
@Override
public void getAllImage(BaseCallback<List<ImageModel>> callback) {
}
}
本地数据源:数据源来自于Provider,lib中将Provider封装了,直接可以调取数据并且按照时间来排序
ImageLocalDataSource
public class ImageLocalDataSource extends BaseLocalDataSource implements ImageDataSource {
private static volatile ImageLocalDataSource instance;
private ImageLocalDataSource(){
}
public static ImageLocalDataSource getInstance(){
if (instance==null){
synchronized (ImageLocalDataSource.class){
if(instance==null){
instance = new ImageLocalDataSource();
}
}
}
return instance;
}
@Override
public void getAllImage(final BaseCallback<List<ImageModel>> callback) {
ThreadExecutor.getInstance().submit(new Runnable() {
@Override
public void run() {
Logger.d("进入getAllImage");
String[] projection = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DISPLAY_NAME,MediaStore.Images.Media.DATA };
String orderBy = android.provider.ContactsContract.Contacts._ID + " DESC";
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
List<ImageModel> imageModels = null;
try {
imageModels = hContentProvider.query(projection,orderBy,uri,ImageModel.class);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
callback.onSuccess(imageModels);
}
});
}
}
之后建立数据仓库类
public class ImagesRepository extends BaseRepository<ImageLocalDataSource,ImageRemoteDataSource> implements ImageDataSource{
List<ImageModel> url;
private static volatile ImagesRepository instance;
public static ImagesRepository getInstance(){
if (instance==null){
synchronized (ImagesRepository.class){
if(instance==null){
instance = new ImagesRepository(ImageLocalDataSource.getInstance(),ImageRemoteDataSource.getInstance());
}
}
}
return instance;
}
protected ImagesRepository(ImageLocalDataSource localDataSource, ImageRemoteDataSource remoteDataSource) {
super(localDataSource, remoteDataSource);
}
@Override
public void getAllImage(BaseCallback<List<ImageModel>> callback) {
localDataSource.getAllImage(callback);
}
}
写法是采用在activity中包fragment的方法
之后我们建立了activity的layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.jcb.www.jcbmanager.activity.ImagesActivity">
<FrameLayout
android:id="@+id/images_framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"></FrameLayout>
</RelativeLayout>
再建立fragment的layout,一如既往的采用RecyclerView
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.jcb.www.jcbmanager.fragment.ImagesFragment">
<android.support.v7.widget.RecyclerView
android:id="@+id/images_Recycler"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</FrameLayout>
之后建立我们需要的cell图像采用 SimpleDraweeView
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
card_view:cardBackgroundColor="#aaaab1"
card_view:cardCornerRadius="3dp"
card_view:cardPreventCornerOverlap="true"
card_view:cardUseCompatPadding="true"
card_view:contentPadding="4dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!--<com.facebook.drawee.view.SimpleDraweeView-->
<!--android:layout_width="100dp"-->
<!--android:layout_height="100dp"-->
<!--fresco:actualImageScaleType="focusCrop"-->
<!--android:layout_centerVertical="true"-->
<!--android:id="@+id/iamges_im" />-->
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/iamges_im"
android:layout_width="100dp"
android:layout_height="100dp"
fresco:actualImageScaleType="focusCrop"
android:layout_centerVertical="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/image_check"
android:src="@drawable/jy_checkbox_off"
android:layout_alignParentTop="true"
android:layout_alignRight="@+id/iamges_im"
android:layout_alignEnd="@+id/iamges_im" />
</RelativeLayout>
</android.support.v7.widget.CardView>
资料图
activity代码如下 (最近lib进行了更改,这块代码还没改掉)
public class ImagesActivity extends BaseActivity implements ImagesFragment.OnFragmentInteractionListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_images);
ActivityUtils.getFragment(getSupportFragmentManager(),R.id.images_framelayout, ImagesFragment.newInstance());
}
}
创建adapter
public class ImagesRecyclerAdapter extends RecyclerView.Adapter<ImagesRecyclerAdapter.ImageViewHoder>{
private List<ImageModel> urls;
private ImagesFragment.OnFragmentInteractionListener interactionListener;
public ImagesRecyclerAdapter(List<ImageModel> urls,ImagesFragment.OnFragmentInteractionListener interactionListener){
this.urls = urls;
this.interactionListener = interactionListener;
}
@Override
public ImageViewHoder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.images_image,parent,false);
return new ImageViewHoder(view);
}
@Override
public void onBindViewHolder(final ImageViewHoder holder, int position) {
holder.url = urls.get(position);
UImage.showThumb(Uri.fromFile(new File(holder.url.get_data())), holder.imageView,200,200);
setImage(holder.check,R.drawable.jy_checkbox_off);
if(holder.url.isCheck()){
setImage(holder.check,R.drawable.jy_checkbox_on);
}else{
setImage(holder.check,R.drawable.jy_checkbox_off);
}
holder.item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent it = new Intent();
it.setClass(ActivityManager.peekTopActivity(), BigImageActivity.class);
it.putExtra(BigImageActivity.UTI,holder.url.get_data());
ActivityManager.peekTopActivity().startActivity(it);
}
});
holder.check.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageView check = (ImageView)v;
if(holder.url.isCheck()){
setImage(check,R.drawable.jy_checkbox_off);
holder.url.setCheck(false);
}else{
setImage(check,R.drawable.jy_checkbox_on);
holder.url.setCheck(true);
}
}
});
}
public void setImage(ImageView check,int res){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
check.setBackground(ActivityManager.peekTopActivity().getResources().getDrawable(res,ActivityManager.peekTopActivity().getTheme()));
}else{
check.setBackground(ActivityManager.peekTopActivity().getResources().getDrawable(res));
}
}
@Override
public int getItemCount() {
if(urls==null){
return 0;
}
return urls.size();
}
class ImageViewHoder extends RecyclerView.ViewHolder{
private final SimpleDraweeView imageView;
private final ImageView check;
private final View item;
private ImageModel url;
public ImageViewHoder(View itemView) {
super(itemView);
this.item = itemView;
imageView = (SimpleDraweeView) itemView.findViewById(R.id.iamges_im);
check = (ImageView) itemView.findViewById(R.id.image_check);
}
}
}
fragment代码如下,主要是调用数据源数据进行显示的
public class ImagesFragment extends BaseFragment {
private OnFragmentInteractionListener mListener;
public ImagesFragment() {
}
public static ImagesFragment newInstance() {
ImagesFragment fragment = new ImagesFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
RecyclerView recyclerView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_images, container, false);
Context context = view.getContext();
recyclerView = getView(view,R.id.images_Recycler);
recyclerView.setLayoutManager(new GridLayoutManager(context,3));
Logger.d("进入imagesfragemt");
ImagesRepository.getInstance().getAllImage(new BaseDataSource.BaseCallback<List<ImageModel>>() {
@Override
public void onSuccess(final List<ImageModel> imageModels) {
//Logger.d(imageModels.size()+ HJson.toJson(imageModels));
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
recyclerView.setAdapter(new ImagesRecyclerAdapter(imageModels,mListener));
}
});
}
@Override
public void onFailure(DataSourceException e) {
}
});
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
其实到这里代码还是没写完呢,只是展示了图片,代码后续部分,大家就自行完成好了,如果我有心情的话我会把我仿照微信的整套代码全部贴出到github上,如有什么建议或者意见请在下面评论,我会偶尔看的
热门评论
感觉CSDN上有类似的实现方法。
赞一下
赞自己