• UID12
  • 登录2016-06-14
  • 粉丝112
  • 关注50
  • 发帖1415
  • 主页
  • 金币8548枚
社区居民
最爱沙发
忠实会员
喜欢达人
原创写手
极分享 发布于2015-12-30 18:18
45/17640

惊艳的App引导页:背景图片切换加各个页面动画效果

楼层直达
前言:不知不觉中又加班到了10点半,整个启动页面做了一天多的时间,一共有三个页面,每个页面都有动画效果,动画效果调试起来麻烦,既要跟ios统一,又要匹配各种不同的手机,然后产品经理还有可能在中途改需求,程序员各种苦逼有木有,在这个过程中也学到了蛮多东西的,所以写一篇博客跟大家分享一下.

先看效果图:



1.显示三个页面的Activity  用view pager去加载三个fragment实现,控制点点点的切换,监听view pager的切换,控制fragment动画的开始跟结束,重写了view pager,实现了背景图片的移动效果.
/** 
 * 主Activity 
 * @author ansen 
 * @create time 2015-08-07 
 */  
public class KaKaLauncherActivity extends FragmentActivity {  
    private GuideViewPager vPager;  
    private List<LauncherBaseFragment> list = new ArrayList<LauncherBaseFragment>();  
    private BaseFragmentAdapter adapter;  
   
    private ImageView[] tips;  
    private int currentSelect;   
       
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_luancher_main);  
           
        //初始化点点点控件  
        ViewGroup group = (ViewGroup)findViewById(R.id.viewGroup);  
        tips = new ImageView[3];  
        for (int i = 0; i < tips.length; i++) {  
            ImageView imageView = new ImageView(this);  
            imageView.setLayoutParams(new LayoutParams(10, 10));  
            if (i == 0) {  
                imageView.setBackgroundResource(R.drawable.page_indicator_focused);  
            } else {  
                imageView.setBackgroundResource(R.drawable.page_indicator_unfocused);  
            }  
            tips=imageView;  
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));  
            layoutParams.leftMargin = 20;//设置点点点view的左边距  
            layoutParams.rightMargin = 20;//设置点点点view的右边距  
            group.addView(imageView,layoutParams);  
        }  
 
        //获取自定义viewpager 然后设置背景图片  
        vPager = (GuideViewPager) findViewById(R.id.viewpager_launcher);  
        vPager.setBackGroud(BitmapFactory.decodeResource(getResources(),R.drawable.bg_kaka_launcher));  
 
        /** 
         * 初始化三个fragment  并且添加到list中 
         */  
        RewardLauncherFragment rewardFragment = new RewardLauncherFragment();  
        PrivateMessageLauncherFragment privateFragment = new PrivateMessageLauncherFragment();  
        StereoscopicLauncherFragment stereoscopicFragment = new StereoscopicLauncherFragment();  
        list.add(rewardFragment);  
        list.add(privateFragment);  
        list.add(stereoscopicFragment);  
 
        adapter = new BaseFragmentAdapter(getSupportFragmentManager(),list);  
        vPager.setAdapter(adapter);  
        vPager.setOffscreenPageLimit(2);  
        vPager.setCurrentItem(0);  
        vPager.setOnPageChangeListener(changeListener);  
    }  
 
    /** 
     * 监听viewpager的移动 
     */  
    OnPageChangeListener changeListener=new OnPageChangeListener() {  
        @Override  
        public void onPageSelected(int index) {  
            setImageBackground(index);//改变点点点的切换效果  
            LauncherBaseFragment fragment=list.get(index);  
 
            list.get(currentSelect).stopAnimation();//停止前一个页面的动画  
            fragment.startAnimation();//开启当前页面的动画  
 
            currentSelect=index;  
        }  
 
        @Override  
        public void onPageScrolled(int arg0, float arg1, int arg2) {}  
        @Override  
        public void onPageScrollStateChanged(int arg0) {}  
    };  
 
 
    /** 
     * 改变点点点的切换效果 
     * @param selectItems 
     */  
    private void setImageBackground(int selectItems) {  
        for (int i = 0; i < tips.length; i++) {  
            if (i == selectItems) {  
                tips.setBackgroundResource(R.drawable.page_indicator_focused);  
            } else {  
                tips.setBackgroundResource(R.drawable.page_indicator_unfocused);  
            }  
        }  
    }  
}


2.重写viewpager   在dispatchDraw方法中控制显示的背景图片区域,
/** 
 * 重写ViewPager  主要做一个切换背景的功能 
 * @author ansen 
 * @create time 2015-08-07 
 */  
public class GuideViewPager extends ViewPager {  
    private Bitmap bg;  
    private Paint b = new Paint(1);  
       
    public GuideViewPager(Context context) {  
        super(context);  
    }  
   
    public GuideViewPager(Context context, AttributeSet attrs) {  
        super(context, attrs);  
    }  
   
    @Override  
    protected void dispatchDraw(Canvas canvas) {  
        if (this.bg != null) {  
            int width = this.bg.getWidth();  
            int height = this.bg.getHeight();  
            int count = getAdapter().getCount();  
            int x = getScrollX();  
            // 子View中背景图片需要显示的宽度,放大背景图或缩小背景图。  
            int n = height * getWidth() / getHeight();  
               
            /** 
             * (width - n) / (count - 1)表示除去显示第一个ViewPager页面用去的背景宽度,剩余的ViewPager需要显示的背景图片的宽度。 
             * getWidth()等于ViewPager一个页面的宽度,即手机屏幕宽度。在该计算中可以理解为滑动一个ViewPager页面需要滑动的像素值。 
             * ((width - n) / (count - 1)) /getWidth()也就表示ViewPager滑动一个像素时,背景图片滑动的宽度。 
             * x * ((width - n) / (count - 1)) /  getWidth()也就表示ViewPager滑动x个像素时,背景图片滑动的宽度。 
             * 背景图片滑动的宽度的宽度可以理解为背景图片滑动到达的位置。 
             */  
            int w = x * ((width - n) / (count - 1)) / getWidth();  
            canvas.drawBitmap(this.bg, new Rect(w, 0, n + w, height), new Rect( x, 0, x + getWidth(), getHeight()), this.b);  
        }  
        super.dispatchDraw(canvas);  
    }  
       
    public void setBackGroud(Bitmap paramBitmap) {  
        this.bg = paramBitmap;  
        this.b.setFilterBitmap(true);  
    }  
}


3.主体布局文件  上面放一个自定义的viewpager  下面放一个显示点点的RelativeLayout
<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" >  
   
    <com.example.view.GuideViewPager  
        android:id="@+id/viewpager_launcher"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent" />  
   
    <RelativeLayout  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:orientation="vertical" >  
   
        <LinearLayout  
            android:id="@+id/viewGroup"  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:layout_alignParentBottom="true"  
            android:layout_marginBottom="30dp"  
            android:gravity="center_horizontal"  
            android:orientation="horizontal" />  
    </RelativeLayout>  
   
</RelativeLayout>


4.ViewPager适配器
/** 
 * Viewpager适配器 
 * @author apple 
 * 
 */  
public class BaseFragmentAdapter extends FragmentStatePagerAdapter {  
    private List<LauncherBaseFragment>list;  
    public BaseFragmentAdapter(FragmentManager fm, List<LauncherBaseFragment> list) {  
        super(fm);  
        this.list = list;  
    }  
   
    public BaseFragmentAdapter(FragmentManager fm) {  
        super(fm);  
    }  
   
    @Override  
    public Fragment getItem(int arg0) {  
        return list.get(arg0);  
    }  
   
    @Override  
    public int getCount() {  
        return list.size();  
    }  
}

5.Fragment抽象类 有两个抽象方法,开启动画跟停止动画  所有的Fragment都继承这个类  Viewpager切换的时候可以更好的控制每个Fragment开启动画,结束动画
/** 
 * Fragment抽象类 
 * @author ansen 
 *  
 */  
public abstract class LauncherBaseFragment extends Fragment{  
    public abstract void  startAnimation();  
    public abstract void  stopAnimation();  
}

6.打赏页Fragment  三个动画效果  硬币向下移动动画+打赏图片缩放动画+改变打赏图片透明度然后隐藏图片
/** 
 * 打赏页面 
 * @author ansen 
 * @create time 2015-08-07 
 */  
public class RewardLauncherFragment extends LauncherBaseFragment{  
    private ImageView ivReward;  
    private ImageView ivGold;  
       
    private Bitmap goldBitmap;  
    private boolean started;//是否开启动画(ViewPage滑动时候给这个变量赋值)  
       
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
        View rooView=inflater.inflate(R.layout.fragment_reward_launcher, null);  
        ivGold=(ImageView) rooView.findViewById(R.id.iv_gold);  
        ivReward=(ImageView) rooView.findViewById(R.id.iv_reward);  
           
        //获取硬币的高度  
        goldBitmap=BitmapFactory.decodeResource(getActivity().getResources(),R.drawable.icon_gold);  
        startAnimation();  
        return rooView;  
    }  
       
    public void startAnimation(){  
        started=true;  
           
        //向下移动动画 硬币的高度*2+80     
        TranslateAnimation translateAnimation=new TranslateAnimation(0,0,0,goldBitmap.getHeight()*2+80);  
        translateAnimation.setDuration(500);  
        translateAnimation.setFillAfter(true);  
           
        ivGold.startAnimation(translateAnimation);  
        translateAnimation.setAnimationListener(new AnimationListener() {  
            @Override  
            public void onAnimationStart(Animation animation) {}  
            @Override  
            public void onAnimationEnd(Animation animation){  
                if(started){  
                    ivReward.setVisibility(View.VISIBLE);  
                    //硬币移动动画结束开启缩放动画  
                    Animation anim=AnimationUtils.loadAnimation(getActivity(),R.anim.reward_launcher);    
                    ivReward.startAnimation(anim);  
                    anim.setAnimationListener(new AnimationListener(){  
                        @Override    
                        public void onAnimationStart(Animation animation) {}    
                        @Override    
                        public void onAnimationRepeat(Animation animation) {}    
                        @Override    
                        public void onAnimationEnd(Animation animation) {  
                                //缩放动画结束 开启改变透明度动画  
                                AlphaAnimation alphaAnimation=new AlphaAnimation(1,0);  
                                alphaAnimation.setDuration(1000);  
                                ivReward.startAnimation(alphaAnimation);  
                                alphaAnimation.setAnimationListener(new AnimationListener() {  
                                    @Override  
                                    public void onAnimationStart(Animation animation) {}  
                                    @Override  
                                    public void onAnimationRepeat(Animation animation) {}  
                                    @Override  
                                    public void onAnimationEnd(Animation animation) {  
                                        //透明度动画结束隐藏图片  
                                        ivReward.setVisibility(View.GONE);  
                                    }  
                            });  
                        }  
                    });  
                }  
            }  
            @Override  
            public void onAnimationRepeat(Animation animation) {}  
        });  
    }  
       
    @Override  
    public void stopAnimation(){  
        started=false;//结束动画时标示符设置为false  
        ivGold.clearAnimation();//清空view上的动画  
    }  
}


7.私信页面   四个动画效果   并且四个动画都相同,其实只要我们实现了一个,其他的基本都很容易了.   依次实现四个图片的放大然后还原

/** 
 * 私信 
 * @author ansen 
 */  
public class PrivateMessageLauncherFragment extends LauncherBaseFragment{  
    private ImageView ivLikeVideo,ivThinkReward,ivThisWeek,ivWatchMovie;  
       
    private Animation likeAnimation,thinkAnimation,watchAnimation,thisWeekAnimation;  
       
    private boolean started;//是否开启动画  
       
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
        View rooView=inflater.inflate(R.layout.fragment_private_message_launcher, null);  
           
        ivLikeVideo=(ImageView) rooView.findViewById(R.id.iv_private_message_like_video);  
        ivThinkReward=(ImageView) rooView.findViewById(R.id.iv_private_message_think_reward);  
        ivWatchMovie=(ImageView) rooView.findViewById(R.id.iv_private_message_watch_movie);  
        ivThisWeek=(ImageView) rooView.findViewById(R.id.private_message_this_week);  
        return rooView;  
    }  
       
    public void stopAnimation(){  
        //动画开启标示符设置成false     
        started=false;  
        /** 
         * 清空所有控件上的动画 
         */  
        ivLikeVideo.clearAnimation();  
        ivThinkReward.clearAnimation();  
        ivWatchMovie.clearAnimation();  
        ivThisWeek.clearAnimation();  
    }  
       
       
    public void startAnimation(){  
        started=true;  
           
        /** 
         * 每次开启动画前先隐藏控件 
         */  
        ivLikeVideo.setVisibility(View.GONE);  
        ivThinkReward.setVisibility(View.GONE);  
        ivWatchMovie.setVisibility(View.GONE);  
        ivThisWeek.setVisibility(View.GONE);  
           
        new Handler().postDelayed(new Runnable() {//延时0.5秒之后开启喜欢视频动画  
            @Override  
            public void run(){  
                if(started)  
                    likeVideoAnimation();  
            }  
        },500);  
    }  
       
    /** 
     * 好喜欢你的视频 
     */  
    private void likeVideoAnimation(){  
        ivLikeVideo.setVisibility(View.VISIBLE);  
           
        likeAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);  
        ivLikeVideo.startAnimation(likeAnimation);//开启动画  
        likeAnimation.setAnimationListener(new AnimationListener(){    
            @Override    
            public void onAnimationStart(Animation animation) {}    
            @Override    
            public void onAnimationRepeat(Animation animation) {}    
            @Override    
            public void onAnimationEnd(Animation animation) {//监听动画结束  
                    if(started)  
                        thinkReward();  
            }    
        });   
    }  
       
    /** 
     * 谢谢你的打赏 
     */  
    private void thinkReward(){  
        ivThinkReward.setVisibility(View.VISIBLE);  
        thinkAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);  
        ivThinkReward.startAnimation(thinkAnimation);  
        thinkAnimation.setAnimationListener(new AnimationListener(){    
            @Override    
            public void onAnimationStart(Animation animation) {}    
            @Override    
            public void onAnimationRepeat(Animation animation) {}    
            @Override    
            public void onAnimationEnd(Animation animation) {  
                if(started)  
                    watchMovie();  
            }    
        });   
    }  
       
    /** 
     * 一起看个电影呗 
     */  
    private void watchMovie(){  
        ivWatchMovie.setVisibility(View.VISIBLE);  
        watchAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);  
        ivWatchMovie.startAnimation(watchAnimation);  
        watchAnimation.setAnimationListener(new AnimationListener(){    
            @Override    
            public void onAnimationStart(Animation animation) {}    
            @Override    
            public void onAnimationRepeat(Animation animation) {}    
            @Override    
            public void onAnimationEnd(Animation animation) {  
                if(started)  
                    thisWeek();  
            }    
        });   
    }  
       
    /** 
     * 好啊  这周末有空 
     */  
    private void thisWeek(){  
        ivThisWeek.setVisibility(View.VISIBLE);  
        thisWeekAnimation = AnimationUtils.loadAnimation(getActivity(),R.anim.private_message_launcher);    
        ivThisWeek.startAnimation(thisWeekAnimation);  
    }  
}

8.最后一个引导页  就两个动画  图片的放大跟缩小,其实用xml布局的话一个动画就能搞定,跟私信页面的动画差不多.小伙伴写的代码.这里换了一种方式.代码比较多.
/** 
 * 最后一个 
 * @author apple 
 */  
public class StereoscopicLauncherFragment extends LauncherBaseFragment implements OnClickListener{  
    private static final float ZOOM_MAX = 1.3f;  
    private static final  float ZOOM_MIN = 1.0f;  
       
    private ImageView imgView_immediate_experience;  
       
    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {  
        View rooView=inflater.inflate(R.layout.fragment_stereoscopic_launcher, null);  
        imgView_immediate_experience=(ImageView) rooView.findViewById(R.id.imgView_immediate_experience);  
        imgView_immediate_experience.setOnClickListener(this);  
        return rooView;  
    }  
       
    public void playHeartbeatAnimation(){  
            /** 
             * 放大动画 
             */  
        AnimationSet animationSet = new AnimationSet(true);  
        animationSet.addAnimation(new ScaleAnimation(ZOOM_MIN, ZOOM_MAX, ZOOM_MIN, ZOOM_MAX, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f));  
        animationSet.addAnimation(new AlphaAnimation(1.0f, 0.8f));  
    
        animationSet.setDuration(500);  
        animationSet.setInterpolator(new AccelerateInterpolator());  
        animationSet.setFillAfter(true);  
    
        animationSet.setAnimationListener(new AnimationListener() {  
            @Override  
            public void onAnimationStart(Animation animation) {  
            }  
    
            @Override  
            public void onAnimationRepeat(Animation animation) {  
            }  
    
            @Override  
            public void onAnimationEnd(Animation animation) {  
                    /** 
                     * 缩小动画 
                     */  
                AnimationSet animationSet = new AnimationSet(true);  
                animationSet.addAnimation(new ScaleAnimation(ZOOM_MAX, ZOOM_MIN, ZOOM_MAX,ZOOM_MIN, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f));  
                animationSet.addAnimation(new AlphaAnimation(0.8f, 1.0f));  
                animationSet.setDuration(600);  
                animationSet.setInterpolator(new DecelerateInterpolator());  
                animationSet.setFillAfter(false);  
                 // 实现心跳的View  
                imgView_immediate_experience.startAnimation(animationSet);  
            }  
        });  
         // 实现心跳的View  
        imgView_immediate_experience.startAnimation(animationSet);  
    }   
   
    @Override  
    public void onClick(View v) {  
//      Intent intent = new Intent();  
//      intent.setClass(getActivity(),MainActivity.class);  
//      startActivity(intent);  
//      getActivity().finish();  
    }  
   
    @Override  
    public void startAnimation() {  
        playHeartbeatAnimation();  
    }  
   
    @Override  
    public void stopAnimation() {  
           
    }  
}

最后总结:以上就是三个引导页的核心代码了,还有一些布局文件,动画效果的布局文件我就不一一贴出来的,大家可以去下载我的源码,在这个过程中碰到的几个大的问题说明一下.
1.viewpager切换的时候要结束上个fragment的动画   我是通过boolean变量去控制的
2.背景图片移动的效果    之前自己走了很多弯路,后面在网上找了一个demo拿过来用了.因为大家都有开源精神所以这里省了很多功夫
3.图片放大缩小以前居然不知道一个xml动画布局就能搞定.之前一直想办法用两个动画实现


看看时间一篇博客写了一个半小时,都12点了,办公室一个人敲打着键盘,记录着这两天做过的东西,才发现这也是一件很惬意的事情。。。。闪人。。。回家.


源代码:

来源:http://www.cnblogs.com/yishaochu/p/5078577.html
        附件名称/大小 下载 更新 附加说明
TestLauncher.zip (2760KB)  281 2015-12-30 18:17

0人打赏
  • UID381
  • 登录2016-01-26
  • 粉丝2
  • 关注3
  • 发帖15
  • 主页
  • 金币45枚
社区居民
我心飞扬不飘荡 发布于2015-12-31 11:02
沙发F
这源码我下载的怎么不是同一个文件啊
我心飞扬不飘荡
  • UID15
  • 登录2017-07-17
  • 粉丝48
  • 关注40
  • 发帖447
  • 主页
  • 金币1848枚
社区居民
喜欢达人
原创写手
janking 发布于2015-12-31 11:50
板凳F
我心飞扬不飘荡:这源码我下载的怎么不是同一个文件啊回到原帖
不一样嘛?
  • UID434
  • 登录2016-02-18
  • 粉丝1
  • 关注1
  • 发帖7
  • 主页
  • 金币10枚
lee小杰 发布于2016-01-07 11:03
地板F
刚好有用
  • UID3524
  • 登录2016-01-11
  • 粉丝0
  • 关注0
  • 发帖10
  • 主页
  • 金币0枚
社区居民
diskkiller 发布于2016-01-11 00:07
4楼F
厉害  谢谢分享
  • UID3524
  • 登录2016-01-11
  • 粉丝0
  • 关注0
  • 发帖10
  • 主页
  • 金币0枚
社区居民
diskkiller 发布于2016-01-11 00:07
5楼F
可以参考一下
  • UID3636
  • 登录2016-01-11
  • 粉丝0
  • 关注0
  • 发帖1
  • 主页
  • 金币10枚
社区居民
gongchengshi 发布于2016-01-11 15:35
6楼F
下载不了?
  • UID3757
  • 登录2016-01-18
  • 粉丝0
  • 关注0
  • 发帖3
  • 主页
  • 金币13枚
615'空间 发布于2016-01-15 16:46
7楼F
我比较关注适配是怎么做的?
  • UID4248
  • 登录2016-01-19
  • 粉丝0
  • 关注0
  • 发帖1
  • 主页
  • 金币6枚
社区居民
醉意不再酒 发布于2016-01-19 14:21
8楼F
f看看,!
  • UID5715
  • 登录2016-07-22
  • 粉丝0
  • 关注0
  • 发帖4
  • 主页
  • 金币28枚
社区居民
少年游侠客 发布于2016-02-01 13:35
9楼F
特效太丰富啦!
  • UID1524
  • 登录2016-03-16
  • 粉丝0
  • 关注0
  • 发帖1
  • 主页
  • 金币33枚
社区居民
toherrt 发布于2016-02-01 15:10
10楼F
效果不错
  • UID5118
  • 登录2016-02-03
  • 粉丝1
  • 关注0
  • 发帖2
  • 主页
  • 金币19枚
社区居民
Lizhy 发布于2016-02-01 16:12
11楼F
效果棒棒哒。一号还在上班额
  • UID6353
  • 登录2016-07-26
  • 粉丝0
  • 关注1
  • 发帖12
  • 主页
  • 金币47枚
发布于2016-02-04 14:35
12楼F
特效很棒啦!每次看到用Eclipse的就觉得亲切
  • UID6495
  • 登录2016-07-04
  • 粉丝0
  • 关注0
  • 发帖3
  • 主页
  • 金币16枚
发布于2016-02-07 17:22
13楼F
特效很棒啦!每次看到用Eclipse的就觉得亲切
  • UID15
  • 登录2017-07-17
  • 粉丝48
  • 关注40
  • 发帖447
  • 主页
  • 金币1848枚
社区居民
喜欢达人
原创写手
janking 发布于2016-02-10 20:31
14楼F
:特效很棒啦!每次看到用Eclipse的就觉得亲切回到原帖
那是
  • UID6552
  • 登录2016-02-27
  • 粉丝0
  • 关注0
  • 发帖5
  • 主页
  • 金币41枚
社区居民
忠实会员
TENDER 发布于2016-02-11 01:16
15楼F
大神,不错,好看
  • UID6770
  • 登录2016-02-19
  • 粉丝0
  • 关注0
  • 发帖6
  • 主页
  • 金币7枚
卡布罗尼 发布于2016-02-14 14:52
16楼F
很漂亮··动画效果非常棒!
  • UID6833
  • 登录2016-03-28
  • 粉丝0
  • 关注0
  • 发帖2
  • 主页
  • 金币2枚
qq_iGha79G14554 发布于2016-02-15 09:07
17楼F
来看每个fragment中的布局和动画
1 2 3
您没填页码……^^页码应该是数字才对吧!^^零页?你当我是实体书……^^负数页……你又调皮了!^^帖子君一共才 ^^ 页……^^本页就是第 ^^ 页。
perv die Page1of3 next
您需要登录后才可以回帖
发表回复
极贡献
技术问答
专题荟萃
程序人生
视觉设计
Android开发
iOS开发
编程语言
前端开发
后端开发
服务器架构
软件测试
运维方案
创业路上



最热文章墙

  • 79397/378   【精品推荐】200多种Android动画效果的强悍框架,太全了,不看这个,再有动画的问题,不理你了^@^

  • 45296/191   情人节福利,程序员表白的正确姿势:改几行代码就变成自己的表白了

  • 44990/0   Python爬虫:常用浏览器的useragent

  • 41473/260   【精品推荐】Android版产品级的音乐播放器源码,功能太强大了,最好的产品原型有木有?

  • 38683/145   省时省力的Android组件群来了,非常棒的原型参考

  • 30061/142   2016抢红包软件及源码

  • 29293/2   超全!整理常用的iOS第三方资源

  • 29289/71   原创表白APP,以程序员的姿势备战新年后的7夕,持续完善中!

  • 24354/160   Android版类似UC浏览器:非常赞,产品级的源码

  • 22868/30   麻省理工的一帮疯子,真的实现了随意操控万物!(绝对黑科技)

  • 22566/25   Android工程师面试题大全

  • 22492/27   2016程序员跳槽全攻略

  • 21953/9   GitHub上排名前50的iOS项目:总有一款你用得着

  • 20910/20   码魂:程序员的牛B漫画

  • 19063/85   Android小而全的博客源码:非常适合全面掌握开发技巧

  • 19051/73   【持续更新中】Android福利贴(二):资料源码大放送

  • 19018/10   2016年最全的Android面试考题+答案 精编版

  • 18920/42   一个绚丽的loading动效分析与实现!

  • 18765/3   吐槽那些程序员的搞笑牛逼注释

  • 17640/45   惊艳的App引导页:背景图片切换加各个页面动画效果

  • 17633/1   iOS 动画总结

  • 17510/82   仿京东商城客户端Android最新版,不错的原型和学习资料

  • 17470/104   Android带弹幕的视频播放器源码,来自大名鼎鼎的Bilibili弹幕网站

  • 17148/23   个人收集的Android 各类功能源代码

  • 16688/5   新一代Android渠道打包工具:1000个渠道包只需要5秒

  • 16618/21   Android福利第三波【Android电子书】

  • 16438/53   基于瀑布流的美女图片浏览App,有注释的源代码

  • 16418/81   【精品推荐】类似360安全卫士安Android源码:非常赞的产品原型

  • 16404/10   女程序员的梦,众网友的神回复

  • 16363/0   iOS中文版资源库,非常全

  • 16341/17   用JavaScript 来开发iOS和Android 原生应用:React Native开源框架中文版来啦

  • 16094/11   年会上现场review代码是怎么样的体验!

  • 16042/23   珍藏多年的素材,灵感搜寻网站

  • 15524/18   65条最常用正则表达式,你要的都在这里了

  • 14853/15   基于Android支付宝支付设计和开发方案

  • 14258/11   有木有这样一张酷图帮你集齐所有git命令超实用

  • 14189/17   什么是真正的黑客:收获12200+Stars,人气远超微软开源VS

  • 13970/46   在线音乐播放器完整版(商用级的源码):非常赞,可听免费高品质专辑

  • 13719/0   GitHub iOS 库和框架Top100 

  • 13671/61   【技巧一】搭配Android Studio,如何实现App远程真机debug?

  • 13566/7   用程序员的姿势抢过年的火车票

  • 13522/7   一张图搞定iOS学习路线,非常全面

  • 13149/10   成为Java顶尖程序员 ,看这11本书就够了

  • 13107/10   微信支付终于成功了(安卓,iOS),在此分享

  • 12998/18   一张图搞定Android学习路线,非常全面

  • 12810/29   【持续更新中】Android福利贴(一):资料源码

  • 12745/3   基于Node.js的强大爬虫,能直接发布抓取的文章哦

  • 12490/4   46 个非常有用的 PHP 代码片段

  • 12013/3   即时通信第三方库

  • 11452/8   流媒体视频直播方案

  • 11382/18   八个最优秀的Android Studio插件

  • 11256/9   B站建开源工作组:APP想支持炫酷弹幕的看过来

  • 11046/9   烧了5亿美金,这家神秘的公司即将颠覆人类未来!

  • 11031/2   【精品推荐】高质量PHP代码的50个实用技巧:非常值得收藏

  • 10952/10   中国黑客的隐秘江湖:攻守对立,顶尖高手月入千万美元

  • 10226/6   开箱即用!Android四款系统架构工具

  • 10016/10   十大技巧快速提升Android应用开发性能

  • 9973/3   10款GitHub上最火爆的国产开源项目——可以媲美西半球

  • 9919/1   Android性能优化视频,文档以及工具

  • 9808/0   基于node-webkit跨平台应用案例集之(一)

  • 返回顶部