手记

Android开发:仿微信图片选择器

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上,如有什么建议或者意见请在下面评论,我会偶尔看的

12人推荐
随时随地看视频
慕课网APP

热门评论

感觉CSDN上有类似的实现方法。

                            赞一下

                     赞自己

查看全部评论