一个完整的壁纸应用——[仿爱壁纸],从设计到实现的过程

一个完整的壁纸应用——[仿爱壁纸],从设计到实现的过程



正如我的GitHub上的README上说的,偶然之间发现了一个接口,觉得挺有意思的,于是乎,就开始着手的写一个壁纸类应用了,其实之前就一直有这样的想法,但是奈何没有接口,我们先来看下这个项目在初期的时候的预览图

这是写了三天的效果,但是这个其实只是一个完整的框架,后台又写了几天,算是把大部分的功能都完善了

后来又坚持的修改了一下,最后推送到Gank上去了,到这里,我就可以慢慢的来修改这些小细节的东西了,我们来看下具体的实现步骤吧!

一.使用的开源

先来看下我的build.gradle,也就是项目目前所用到的东西

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.0'
    testCompile 'junit:junit:4.12'
    //Material Design
    compile 'com.android.support:cardview-v7:25.0.1'
    compile 'com.android.support:appcompat-v7:25.0.1'
    compile 'com.android.support:design:25.0.1'
    //Retrofit2.0
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    //PhotoView
    compile 'com.github.chrisbanes:PhotoView:1.3.0'
    //Glide
    compile 'com.github.bumptech.glide:glide:3.6.1'
    //CircleImageView
    compile 'de.hdodenhof:circleimageview:2.1.0'
    //RxVolley
    compile 'com.kymjs.rxvolley:rxvolley:1.1.4'
    compile 'com.kymjs.rxvolley:okhttp:1.1.4'
    //JC Play
    compile 'fm.jiecao:jiecaovideoplayer:5.3'
}

在这里,使用了Material Design就不多说了,网络解析我使用了两个库,一个是RxVolley,一个是Retrofit2.0,Retrofit2.0在天气模块进行了尝试,PhotoView还没有使用,但是图片肯定要进行缩放的,图片加载使用了Glide,圆形的头像CircleImageView,已经最后的节操播放器,因为我有准备加入小视频的模块,所有引入了这个源,但是目前还没有使用到,可以看到,其实我们真实的用到的东西并没有很多,但是你这个项目也不大,对吧!

二.项目架构

项目采用的是NavigationView + Fragment的组织架构去搭建的,这也是比较直观和流行的架构了可以看到

项目很舒服,我的Fragment的切换策略采用的是show/hide的方式来处理的,其他倒没有没什么可说的

三.模块的具体实现

关于实现各功能的逻辑,我这里挑一些重点,其他的大家就自己去看Github了

1.首页

主页的实现是ViewPager的轮播加上一个GridView,外部通过一个ScrollView嵌套,这里有几个问题,首先,初始化后GridView会抢占焦点,这是因为两个滑动的冲突导致测量的问题,所有我一进去就手动的滑动到顶部

//滚动到顶部
mHandler.post(new Runnable() {
  @Override
  public void run() {
       mScrollView.fullScroll(ScrollView.FOCUS_UP);
  }
});

并且Gridview也无法计算,所以到导致只出现一个item的现象,这里我是重写了GridView,只需要更改他的测量方法

  @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }

2.相册

相册采用了好几种的加载方式,首先,我会通过内容提供者去查询内存卡的图片

  //获取本地相册
    private void getAllImagePath() {
        Cursor cursor = getActivity().getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
        //遍历相册
        while (cursor.moveToNext()) {
            String path = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA));
            //将图片路径添加到集合
            paths.add(path);
        }
        cursor.close();
    }

同时,因为采用了show/hide的形式,所以,我添加了一个监听

   //视图改变
    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if(!hidden){
            getAllImagePath();
            albumGridAdapter.notifyDataSetChanged();
        }
    }

这样切换后也会去刷新,并且我加入了下拉加载SwipeRefreshLayout去做及时的处理

3.预览

这也是比较重要的环节,我们先看下截图

这里下面下面有几个操作的按钮,首先是分享,然后是点赞,这些没什么问题,这个设置壁纸,还有下载,是核心点,最有边的菜单我会弹出一个PopupWindow来,其实就是游戏和定制,看下我的PopupWindow实现

   //显示菜单window
    private void showMenuWindow() {
        contentView = LayoutInflater.from(this).inflate(R.layout.pop_item_layout, null);
        popWnd = new PopupWindow(this);
        popWnd.setContentView(contentView);
        popWnd.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
        popWnd.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        popWnd.setOutsideTouchable(true);
        popWnd.setBackgroundDrawable(new BitmapDrawable());
        popWnd.showAtLocation(ll_bottom_bar, Gravity.BOTTOM
                , ScreenUtils.getInstance(this).getScreenWidth() / 2
                , 350);
        //这里的350 应该按照View的思路 去进行测量,这里暂时未处理
    }

代码很简单,接着看下载,下载我是用的是RxVolley的下载方式,可以看下他的源码

    /**
     * 下载
     *
     * @param storeFilePath    本地存储绝对路径
     * @param url              要下载的文件的url
     * @param progressListener 下载进度回调
     * @param callback         回调
     */
    public static FileRequest download(String storeFilePath, String url, ProgressListener
            progressListener, HttpCallback callback) {
        RequestConfig config = new RequestConfig();
        config.mUrl = url;
        config.mRetryPolicy = new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
                20, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        FileRequest request = new FileRequest(storeFilePath, config, callback);
        request.setTag(url);
        request.setOnProgressListener(progressListener);
        new Builder().setRequest(request).doTask();
        return request;
    }

最后就是设置壁纸了,这里我有好几个选项

虽然有几个选项,但是都是很简单的,设置桌面壁纸可以直接通过WallpaperManager的setBitmap去实现,锁屏就比较麻烦了,我们通过反射

    //设置锁屏壁纸
    private void setLockScreenWallpaper() {
        Glide.with(this).load(mListBigUrl.get(mGallery.getSelectedItemPosition())).asBitmap().into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                try {
                    //获取类名
                    Class class1 = wpManager.getClass();
                    //获取设置锁屏壁纸的函数
                    Method setWallPaperMethod = class1.getMethod("setBitmapToLockWallpaper", Bitmap.class);
                    //调用锁屏壁纸的函数,并指定壁纸的路径imageFilesPath
                    setWallPaperMethod.invoke(wpManager, resource);
                    Toast.makeText(GalleryActivity.this, "锁屏壁纸设置成功", Toast.LENGTH_SHORT).show();
                } catch (Throwable e) {
                    Toast.makeText(GalleryActivity.this, "锁屏壁纸设置失败", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

而且有点不兼容,我们这里也是要优化下的,当然设置里面也有很多细节没讲,这些就大家自己去挖掘吧,gif在github中,csdn上传有限制!

GitHub:LoveWallpaper

我的群:

如果有谁对深度学习的群感兴趣,可以观看一下这篇文章:

时间: 2024-10-28 19:37:07

一个完整的壁纸应用——[仿爱壁纸],从设计到实现的过程的相关文章

仿百度壁纸客户端(六)——完结篇之Gallery画廊实现壁纸预览已经项目细节优化

仿百度壁纸客户端(六)--完结篇之Gallery画廊实现壁纸预览已经项目细节优化 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 仿百度壁纸客户端(三)--首页单向,双向事件冲突处理,壁纸列表的实现 仿百度壁纸客户端(四)--自定义上拉加载实现精选壁纸墙 仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 仿百度壁纸客

仿百度壁纸客户端(一)——主框架搭建,自定义Tab+ViewPager+Fragment

仿百度壁纸客户端(一)--主框架搭建,自定义Tab+ViewPager+Fragment 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 仿百度壁纸客户端(三)--首页单向,双向事件冲突处理,壁纸列表的实现 仿百度壁纸客户端(四)--自定义上拉加载实现精选壁纸墙 仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 仿百

仿百度壁纸客户端(五)——实现搜索动画GestureDetector手势识别,动态更新搜索关键字

仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 仿百度壁纸客户端(三)--首页单向,双向事件冲突处理,壁纸列表的实现 仿百度壁纸客户端(四)--自定义上拉加载实现精选壁纸墙 仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键

仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图

仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 仿百度壁纸客户端(三)--首页单向,双向事件冲突处理,壁纸列表的实现 仿百度壁纸客户端(四)--自定义上拉加载实现精选壁纸墙 仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 仿百度壁纸客户端(六)-

仿百度壁纸客户端(四)——自定义上拉加载实现精选壁纸墙

仿百度壁纸客户端(四)--自定义上拉加载实现精选壁纸墙 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度壁纸客户端(二)--主页自定义ViewPager广告定时轮播图 仿百度壁纸客户端(三)--首页单向,双向事件冲突处理,壁纸列表的实现 仿百度壁纸客户端(四)--自定义上拉加载实现精选壁纸墙 仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 仿百度壁纸客户端(六)--完结篇之Ga

Android仿百度壁纸客户端之搭建主框架(一)_Android

这是个不错的教程,自己学完了之后就拿出来分享了,本来想一个帖子写完,但是发现这样对自己写博客的效率有点出入,为了让大家看的舒服点,所以分开来写,我们先开看下百度壁纸的客户端是什么样子的 我们先来写个主页的框架,我们新建一个项目--BaiDuWallPaper  写个Item layout_tab_item <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&qu

Android仿百度壁纸客户端之搭建主框架(一)

这是个不错的教程,自己学完了之后就拿出来分享了,本来想一个帖子写完,但是发现这样对自己写博客的效率有点出入,为了让大家看的舒服点,所以分开来写,我们先开看下百度壁纸的客户端是什么样子的 我们先来写个主页的框架,我们新建一个项目--BaiDuWallPaper 写个Item layout_tab_item <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&quo

移动开发-可不可以提供一个完整的安卓项目

问题描述 可不可以提供一个完整的安卓项目 本学期学习移动开发,很想学好这个课程,但是课程结束了,一个东西都没有做出来,有没有感受提供一个移动开发项目,最好可以给出详细的介绍解释,方便新手学习的!谢谢 解决方案 eoe:http://www.eoeandroid.com/ apkbus:http://www.apkbus.com/forum.php 爱盈利:http://bbs.aiyingli.com/forum.php 泡网日:http://www.jcodecraeer.com/

js实现仿爱微网两级导航菜单效果代码_javascript技巧

本文实例讲述了js实现仿爱微网两级导航菜单效果代码.分享给大家供大家参考.具体如下: 这是一款仿爱微网两级导航菜单,tab选项卡形式的导航菜单,原生js做的tab选项卡型的导航菜单,需要鼠标点击才切换出二级子菜单,可修改成鼠标移过去就更换内容的形式. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-fawei-web-nav-menu-style-codes/ 具体代码如下: <html> <head> <title&g