知乎日报客户端--每日看看板块

看完这一篇你应该学会:如何展示照片墙,并且保存图片到本地。效果图:


上一篇讲的是:知乎日报板块的实现

这一篇的知识点有:Okhttp,Picasso,CardView,动态请求权限,创建文件,文件夹,保存图片。

先来布局:

知乎日报客户端--每日看看板块_第1张图片

material-design,用得CardView,使用CardView记得添加  

com.android.support:cardview-v7:27.0.2 依赖

主代码:

public class MeiriFragment extends Fragment {
    private final String TAG = "MeiriFragment";
    private RecyclerView mRecyclerView;
    private int cur = 1;
    private MeiriAdapter mMeiriAdapter;
    private boolean isFirstEnter = true;  //标志是否第一次进入
    boolean isGettingPre = false;  //标识是否正在获取之前的图片
    boolean isEnd = false;  //标志是否图片到底
    private List imgUrls;
    //  private ThumbnailDownloader mThumbnailDownloader;

    public static Fragment newInstance() {
        return new MeiriFragment();
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0x123) {
                Log.d("MeiriFragment", "Handler接受到消息");
                String url = (String) msg.obj;
                Log.d("message===>", url);
            }
        }
    };

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMeiriAdapter = new MeiriAdapter();
        AsyncTask> task = new AsyncTask>() {
            @Override
            protected List doInBackground(Object... objects) {
                return Connect.getMeiriImgUrls(getActivity(), String.valueOf(cur));
            }

            @Override
            protected void onPostExecute(List imgs) {
                super.onPostExecute(imgs);
                imgUrls = imgs;
                mRecyclerView.setAdapter(mMeiriAdapter);
            }
        };
        task.execute();
       /* Handler responseHandler = new Handler();
        mThumbnailDownloader = new ThumbnailDownloader<>(responseHandler);
        mThumbnailDownloader.setTThumbnailDownloadListener(new ThumbnailDownloader.ThumbnailDownloadListener() {
            @Override
            public void onThumbnailDownloaded(MeiriAdapter.MeiriHolder target, Bitmap thumbnail) {
             // target.mImageView.setImageBitmap(thumbnail);
            }
        });
        mThumbnailDownloader.start();
        mThumbnailDownloader.getLooper();
        Log.i(TAG,"background thread started");*/
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.wangyifragmennt, container, false);
        mRecyclerView = v.findViewById(R.id.recyler_view);
        final LinearLayoutManager manager = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(manager);
        BitmapFactory.Options options = new BitmapFactory.Options();
        //mBitmap = CalculateInSampleSize.decodeSampleBitmapFromRes(getResources(),R.drawable.wangyiimg,600,600);
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                Log.i(TAG, "itemCount==> " + manager.getItemCount() + "\n current item position==> " + manager.findLastVisibleItemPosition());
                //  Log.i(TAG,"isEnd==> "+isEnd);

                if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset()
                        >= recyclerView.computeVerticalScrollRange() && isEnd) {
                    Toast.makeText(getActivity(), "没有更多的图片啦", Toast.LENGTH_SHORT).show();
                }


                if (isGettingPre) {
                    return;
                }
                if (manager.getItemCount() - manager.findLastVisibleItemPosition() < 3) {
                    final int preLength = imgUrls.size();
                    isGettingPre = true;
                    AsyncTask task = new AsyncTask() {
                        @Override
                        protected Object doInBackground(Object[] objects) {
                            return Connect.getPreMeiriUrls(String.valueOf(++cur));
                        }

                        @Override
                        protected void onPostExecute(Object o) {
                            super.onPostExecute(o);
                            imgUrls = (List) o;
                            if (preLength == imgUrls.size()) {
                                isEnd = true;
                                return;
                            }
                            mMeiriAdapter.notifyDataSetChanged();
                            isGettingPre = false;
                        }
                    };
                    task.execute();
                }
            }
        });
        return v;
    }

    private class MeiriAdapter extends RecyclerView.Adapter {

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(getActivity()).inflate(R.layout.meiri_layout, parent, false);
            return new MeiriHolder(v);
        }

        @Override
        public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
            //((MeiriHolder)holder).mImageView.setImageBitmap(mBitmap);
//            Message msg = mHandler.obtainMessage(0x123,imgUrls.get(position));
//            mHandler.sendMessage(msg);
            //  mThumbnailDownloader.queueThumbnail((MeiriHolder) holder,imgUrls.get(position));
            // Picasso.with(getActivity()).setIndicatorsEnabled(true);  //用于显示图片从哪里加载【网络,内存,磁盘】
            Picasso.with(getActivity()).load(Uri.parse(imgUrls.get(position))).fit().centerCrop().into(((MeiriHolder) holder).mImageView);
            /*
             * 为什么在这加了fit(),和centerCrop()
             *
            */
            ((MeiriHolder) holder).mImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // Toast.makeText(getActivity(),"点击照片",Toast.LENGTH_SHORT).show();
                    View view = LayoutInflater.from(getActivity()).inflate(R.layout.bigimg, null);
                    ImageView imageView = view.findViewById(R.id.img_container);
                    Log.i(TAG, "拿到的URI是==》:" + imgUrls.get(position));
                    Picasso.with(getActivity()).load(Uri.parse(imgUrls.get(position))).into(imageView);
                    AlertDialog dialog = new AlertDialog.Builder(getActivity(), R.style.Dialog_Fullscreen).setView(view)
                            .setPositiveButton("保存", null)
                            .setNegativeButton("返回", null).create();

                    //这里如果加了.fit()和centerCrop()会不显示图片
                    imageView.setOnTouchListener(new OnDoubleClickListener(new OnDoubleClickListener.DoubleClickCallback() {
                        @Override
                        public void onDoubleClcik() {
                            saveImg(position);
                        }
                    }));

                    imageView.setOnLongClickListener(new View.OnLongClickListener() {
                        @Override
                        public boolean onLongClick(View v) {
                            Log.i(TAG, "url is ==> " + imgUrls.get(position));
                            saveImg(position);
                            return true;
                        }
                    });

                    dialog.show();
                    dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            //Toast.makeText(getActivity(),"保存",Toast.LENGTH_SHORT).show();
                            saveImg(position);
                        }
                    });
                    if (isFirstEnter) {
                        Toast.makeText(getActivity(), "长按图片可以保存哟", Toast.LENGTH_SHORT).show();
                        isFirstEnter = false;
                    }

                }
            });
        }

        @Override
        public int getItemCount() {
            return imgUrls.size();
        }

        public class MeiriHolder extends RecyclerView.ViewHolder {
            public ImageView mImageView;

            public MeiriHolder(View itemView) {
                super(itemView);
                mImageView = itemView.findViewById(R.id.iv_meiri);
            }
        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // mThumbnailDownloader.clearQueue();
    }

    public void saveImg(final int position) {
        if (SaveImg.hasPermission(getActivity())) {
            Picasso.with(getActivity()).load(imgUrls.get(position)).into(new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    Log.i(TAG, "load from==>" + from);
                    boolean hasSaved = SaveImg.saveImg(bitmap, "每日看看-" + String.valueOf(position) + ".jpeg", getActivity());
                    if (hasSaved) {
                        Toast.makeText(getActivity(), "已保存至相册^.^", Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {

                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {

                }
            });
        } else {
            Log.i(TAG,"无权限");
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 0: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(getActivity(), "已获取权限,可以保存图片", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getActivity(), "您拒绝了写文件权限,无法保存图片", Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }
}

说下逻辑吧:

创建fragment时,会返回包含CardView的布局,在onCreate里面先去用AsyncTask联网加载数据,这些数据以json格式返回,此时我用JsonObject解析,拿到json里面每张图片的url,接着讲url都放到一个list集合里面,返回,设置adapter,

adapter里面的bindView会去显示每一个子item,然后用Picasso框架去获取url对应的图片并显示在ImageView里面。

Picasso使用起来很方面,可以链式调用Picasson.with(Context).load(url).fit().centerCrop().into(imageview).

保存图片:

为item设置侦听,点击子项时弹出一个全屏的dialog,点击保存时会先检查是否能够读写sd卡权限,如果没有权限则动态申请

我另外博客有写:

保存bitmap到本地

动态请求权限

ok...

你可能感兴趣的:(知乎日报客户端各个功能的实现,Android知识碎碎片)