新手引导页-ViewPager
2015-12-15 23:29
483 查看
知识点:
ViewPager
Button-Selector
getViewTreeObserver视图树
在splash闪屏动画结束之后,进入手机新手引导页,效果图;
一共有三张图,前两张相同,第三张有一个开始体验按钮。
布局分析:
使用Relativelayout进行总体布局,三张图片使用ViewPager进行布局,并添加一个按钮,在前两页进行隐藏,在第三页进行显示。
下面三个小灰点儿使用Linerlayout进行线性布局,并将LinerLayout嵌套在一个RelativeLayout中,使小红点压在小灰点儿上。
最后根据检测ViewPager滑动事件来进行操作小红点的位置。
整体XML文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="@+id/vp_guide"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25dp"
android:background="@drawable/btn_guide_selector"
android:textColor="@drawable/text_guide_selector"
android:padding="5dp"
android:visibility="invisible"
android:text="开始体验" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp" >
<LinearLayout
android:id="@+id/ll_point_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
<View
android:id="@+id/view_red_point"
android:layout_width="10dp"
android:layout_height="10dp"
android:background="@drawable/shape_point_red"
/>
</RelativeLayout>
</RelativeLayout>
private static final int[] mImageIds = new int[] {
R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3
};
private ViewPager vpguide;
private ArrayList<ImageView> mImageViewList;
mImageViewList =new ArrayList<ImageView>();
for(int i=0;i<mImageIds.length;i++)
{
ImageView image = new ImageView(this);
image.setBackgroundResource(mImageIds[i]);
mImageViewList.add(image); //将图片信息储存在ArrayList中
}
2 ViewPager适配器
class GuideAdapter extends PagerAdapter{
@Override
public int getCount() { // 得到图片的数量
// TODO Auto-generated method stub
return mImageIds.length;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) { //用来比较已存入的图片信息,进而当页面发生变化时,进行图片查找
// TODO Auto-generated method stub
return arg0==arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//把图片放入到container容器中。
container.addView(mImageViewList.get(position));
System.out.println("当前创建图片是: "+position);
return mImageViewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
System.out.println("destroy : "+position+" 图片!");
//销毁时,将页面删除掉
container.removeView((View) object);
//super.destroyItem(container, position, object);
}
}
3 设置适配器
vpguide.setAdapter(new GuideAdapter());
vpguide.setOnPageChangeListener(new GuidePagelistener());
由于存在着状态切换,所以使用Selector来实现这个功能。
字体颜色的切换:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:color="@android:color/black"/>
<item android:color="@android:color/white"/>
</selector>
背景的切换:
可以看到最终的切换实现是在XML中实现的:
android:background="@drawable/btn_guide_selector"
android:textColor="@drawable/text_guide_selector"
<LinearLayout
android:id="@+id/ll_point_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
绘制灰色小点儿,并填充到LinerLayout中:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="@android:color/darker_gray"/>
</shape>
获得LinerLayout布局id: llpointgroup=(LinearLayout) findViewById(R.id.ll_point_group);
//初始化引导页的小圆点
for(int i=0;i<mImageIds.length;i++)
{
View point = new View(this);
LinearLayout.LayoutParams params= new LinearLayout.LayoutParams(10, 10);
if(i>0)
{
params.leftMargin=10;
}
point.setLayoutParams(params);//设置圆点的大小
point.setBackgroundResource(R.drawable.shape_point_gray); //将灰色小点儿添加到LinearLayout中
llpointgroup.addView(point);//将圆点添加给线性布局
}
这样就在拥有了三个灰色小点儿。
同样的方式绘制一个红色小点儿,并压在第一个灰色小点儿上。实现方式是将LinearLayout嵌套在RelativeLayout上,并根据ViewPager滑动事件来动态挪动小红点的位置,来实现动态效果。
红色小点儿:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/holo_red_light" />
</shape>
获得红点id :viewRedPoint=findViewById(R.id.view_red_point);
总体XML:
在viewpager滑动监听事件中进行监听,实现动态变换:
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) { //滑动变化
System.out.println("arg0 : "+arg0+" ;arg1 : "+arg1+";arg2 : "+arg2);
int len = (int)(mPointWidth*arg1)+mPointWidth*arg0;
//获取当前红点的参数
RelativeLayout.LayoutParams layoutparams = (RelativeLayout.LayoutParams)viewRedPoint.getLayoutParams();
layoutparams.leftMargin=len; //设置左边距
viewRedPoint.setLayoutParams(layoutparams);//重新为小圆点设置边距
}
整体GuideActivity:
package com.example.zhihuibj;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.LinearGradient;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout;
public class GuideActivity extends Activity{
private static final int[] mImageIds = new int[] {
R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3
};
private ViewPager vpguide;
private ArrayList<ImageView> mImageViewList; //使用ArrayList储存图片
private LinearLayout llpointgroup; //引导圆点的父控件
private int mPointWidth;//两个圆点之间的距离
private View viewRedPoint; //小红点
private Button btnstart;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//去掉标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_guide);
llpointgroup=(LinearLayout) findViewById(R.id.ll_point_group);
vpguide = (ViewPager)findViewById(R.id.vp_guide); //得到ViewPager控件
viewRedPoint=findViewById(R.id.view_red_point);
btnstart=(Button)findViewById(R.id.btn_start);
//初始化数据
InitViews();
//设置适配器
vpguide.setAdapter(new GuideAdapter());
vpguide.setOnPageChangeListener(new GuidePagelistener());
btnstart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//更新sp,表示已经更新了新手引导页
SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
sp.edit().putBoolean("is_user_guide_showed", true).commit();
startActivity(new Intent(GuideActivity.this, MainActivity.class));
finish();
}
});
}
private void InitViews()
{
mImageViewList =new ArrayList<ImageView>();
for(int i=0;i<mImageIds.length;i++)
{
ImageView image = new ImageView(this);
image.setBackgroundResource(mImageIds[i]);
mImageViewList.add(image); //将图片信息储存在ArrayList中
}
//初始化引导页的小圆点
for(int i=0;i<mImageIds.length;i++)
{
View point = new View(this);
LinearLayout.LayoutParams params= new LinearLayout.LayoutParams(10, 10);
if(i>0)
{
params.leftMargin=10;
}
point.setLayoutParams(params);//设置圆点的大小
point.setBackgroundResource(R.drawable.shape_point_gray); //将灰色小点儿添加到LinearLayout中
llpointgroup.addView(point);//将圆点添加给线性布局
}
//获取视图树:目的是获得小圆点的间距
llpointgroup.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
System.out.println("绘图结束!");
llpointgroup.getViewTreeObserver().removeOnGlobalLayoutListener(this);;
mPointWidth = llpointgroup.getChildAt(1).getLeft()-llpointgroup.getChildAt(0).getLeft();
System.out.println("width"+mPointWidth+"");
}
});
}
class GuidePagelistener implements OnPageChangeListener{
@Override
public void onPageScrollStateChanged(int arg0) { // 状态变化
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) { //滑动变化
System.out.println("arg0 : "+arg0+" ;arg1 : "+arg1+";arg2 : "+arg2);
int len = (int)(mPointWidth*arg1)+mPointWidth*arg0;
//获取当前红点的参数
RelativeLayout.LayoutParams layoutparams = (RelativeLayout.LayoutParams)viewRedPoint.getLayoutParams();
layoutparams.leftMargin=len; //设置左边距
viewRedPoint.setLayoutParams(layoutparams);//重新为小圆点设置边距
}
@Override
public void onPageSelected(int arg0) { //选中变化
if(arg0==mImageIds.length-1)
{
btnstart.setVisibility(View.VISIBLE);
}
else
{
btnstart.setVisibility(View.INVISIBLE);
}
}
}
class GuideAdapter extends PagerAdapter{
@Override
public int getCount() { // 得到图片的数量
// TODO Auto-generated method stub
return mImageIds.length;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) { //用来比较已存入的图片信息,进而当页面发生变化时,进行图片查找
// TODO Auto-generated method stub
return arg0==arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//把图片放入到container容器中。
container.addView(mImageViewList.get(position));
System.out.println("当前创建图片是: "+position);
return mImageViewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
System.out.println("destroy : "+position+" 图片!");
//销毁时,将页面删除掉
container.removeView((View) object);
//super.destroyItem(container, position, object);
}
}
}
/*
* 所有的点击变化都可以使用选择器selector进行设定
*/
ViewPager
Button-Selector
getViewTreeObserver视图树
在splash闪屏动画结束之后,进入手机新手引导页,效果图;
一共有三张图,前两张相同,第三张有一个开始体验按钮。
布局分析:
使用Relativelayout进行总体布局,三张图片使用ViewPager进行布局,并添加一个按钮,在前两页进行隐藏,在第三页进行显示。
下面三个小灰点儿使用Linerlayout进行线性布局,并将LinerLayout嵌套在一个RelativeLayout中,使小红点压在小灰点儿上。
最后根据检测ViewPager滑动事件来进行操作小红点的位置。
整体XML文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="@+id/vp_guide"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25dp"
android:background="@drawable/btn_guide_selector"
android:textColor="@drawable/text_guide_selector"
android:padding="5dp"
android:visibility="invisible"
android:text="开始体验" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp" >
<LinearLayout
android:id="@+id/ll_point_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
<View
android:id="@+id/view_red_point"
android:layout_width="10dp"
android:layout_height="10dp"
android:background="@drawable/shape_point_red"
/>
</RelativeLayout>
</RelativeLayout>
第一步:为ViewPager添加图片
1 数据初始化:private static final int[] mImageIds = new int[] {
R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3
};
private ViewPager vpguide;
private ArrayList<ImageView> mImageViewList;
mImageViewList =new ArrayList<ImageView>();
for(int i=0;i<mImageIds.length;i++)
{
ImageView image = new ImageView(this);
image.setBackgroundResource(mImageIds[i]);
mImageViewList.add(image); //将图片信息储存在ArrayList中
}
2 ViewPager适配器
class GuideAdapter extends PagerAdapter{
@Override
public int getCount() { // 得到图片的数量
// TODO Auto-generated method stub
return mImageIds.length;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) { //用来比较已存入的图片信息,进而当页面发生变化时,进行图片查找
// TODO Auto-generated method stub
return arg0==arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//把图片放入到container容器中。
container.addView(mImageViewList.get(position));
System.out.println("当前创建图片是: "+position);
return mImageViewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
System.out.println("destroy : "+position+" 图片!");
//销毁时,将页面删除掉
container.removeView((View) object);
//super.destroyItem(container, position, object);
}
}
3 设置适配器
vpguide.setAdapter(new GuideAdapter());
vpguide.setOnPageChangeListener(new GuidePagelistener());
第二步:button设置
Button在没有被点击时,是白色字体,红色背景。在被点击时,是黑色字体,黄色背景。由于存在着状态切换,所以使用Selector来实现这个功能。
字体颜色的切换:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:color="@android:color/black"/>
<item android:color="@android:color/white"/>
</selector>
背景的切换:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_pressed="true" android:drawable="@drawable/button_red_pressed"/> <item android:drawable="@drawable/button_red_normal"/> </selector>
可以看到最终的切换实现是在XML中实现的:
android:background="@drawable/btn_guide_selector"
android:textColor="@drawable/text_guide_selector"
第三步:设置动态小点滑动效果
先声明LinerLayout布局:<LinearLayout
android:id="@+id/ll_point_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
绘制灰色小点儿,并填充到LinerLayout中:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="@android:color/darker_gray"/>
</shape>
获得LinerLayout布局id: llpointgroup=(LinearLayout) findViewById(R.id.ll_point_group);
//初始化引导页的小圆点
for(int i=0;i<mImageIds.length;i++)
{
View point = new View(this);
LinearLayout.LayoutParams params= new LinearLayout.LayoutParams(10, 10);
if(i>0)
{
params.leftMargin=10;
}
point.setLayoutParams(params);//设置圆点的大小
point.setBackgroundResource(R.drawable.shape_point_gray); //将灰色小点儿添加到LinearLayout中
llpointgroup.addView(point);//将圆点添加给线性布局
}
这样就在拥有了三个灰色小点儿。
同样的方式绘制一个红色小点儿,并压在第一个灰色小点儿上。实现方式是将LinearLayout嵌套在RelativeLayout上,并根据ViewPager滑动事件来动态挪动小红点的位置,来实现动态效果。
红色小点儿:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/holo_red_light" />
</shape>
获得红点id :viewRedPoint=findViewById(R.id.view_red_point);
总体XML:
<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:layout_marginBottom="10dp" > <LinearLayout android:id="@+id/ll_point_group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > </LinearLayout> <View android:id="@+id/view_red_point" android:layout_width="10dp" android:layout_height="10dp" android:background="@drawable/shape_point_red" /> </RelativeLayout>
在viewpager滑动监听事件中进行监听,实现动态变换:
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) { //滑动变化
System.out.println("arg0 : "+arg0+" ;arg1 : "+arg1+";arg2 : "+arg2);
int len = (int)(mPointWidth*arg1)+mPointWidth*arg0;
//获取当前红点的参数
RelativeLayout.LayoutParams layoutparams = (RelativeLayout.LayoutParams)viewRedPoint.getLayoutParams();
layoutparams.leftMargin=len; //设置左边距
viewRedPoint.setLayoutParams(layoutparams);//重新为小圆点设置边距
}
整体GuideActivity:
package com.example.zhihuibj;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.LinearGradient;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout;
public class GuideActivity extends Activity{
private static final int[] mImageIds = new int[] {
R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3
};
private ViewPager vpguide;
private ArrayList<ImageView> mImageViewList; //使用ArrayList储存图片
private LinearLayout llpointgroup; //引导圆点的父控件
private int mPointWidth;//两个圆点之间的距离
private View viewRedPoint; //小红点
private Button btnstart;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//去掉标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_guide);
llpointgroup=(LinearLayout) findViewById(R.id.ll_point_group);
vpguide = (ViewPager)findViewById(R.id.vp_guide); //得到ViewPager控件
viewRedPoint=findViewById(R.id.view_red_point);
btnstart=(Button)findViewById(R.id.btn_start);
//初始化数据
InitViews();
//设置适配器
vpguide.setAdapter(new GuideAdapter());
vpguide.setOnPageChangeListener(new GuidePagelistener());
btnstart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//更新sp,表示已经更新了新手引导页
SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
sp.edit().putBoolean("is_user_guide_showed", true).commit();
startActivity(new Intent(GuideActivity.this, MainActivity.class));
finish();
}
});
}
private void InitViews()
{
mImageViewList =new ArrayList<ImageView>();
for(int i=0;i<mImageIds.length;i++)
{
ImageView image = new ImageView(this);
image.setBackgroundResource(mImageIds[i]);
mImageViewList.add(image); //将图片信息储存在ArrayList中
}
//初始化引导页的小圆点
for(int i=0;i<mImageIds.length;i++)
{
View point = new View(this);
LinearLayout.LayoutParams params= new LinearLayout.LayoutParams(10, 10);
if(i>0)
{
params.leftMargin=10;
}
point.setLayoutParams(params);//设置圆点的大小
point.setBackgroundResource(R.drawable.shape_point_gray); //将灰色小点儿添加到LinearLayout中
llpointgroup.addView(point);//将圆点添加给线性布局
}
//获取视图树:目的是获得小圆点的间距
llpointgroup.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
System.out.println("绘图结束!");
llpointgroup.getViewTreeObserver().removeOnGlobalLayoutListener(this);;
mPointWidth = llpointgroup.getChildAt(1).getLeft()-llpointgroup.getChildAt(0).getLeft();
System.out.println("width"+mPointWidth+"");
}
});
}
class GuidePagelistener implements OnPageChangeListener{
@Override
public void onPageScrollStateChanged(int arg0) { // 状态变化
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) { //滑动变化
System.out.println("arg0 : "+arg0+" ;arg1 : "+arg1+";arg2 : "+arg2);
int len = (int)(mPointWidth*arg1)+mPointWidth*arg0;
//获取当前红点的参数
RelativeLayout.LayoutParams layoutparams = (RelativeLayout.LayoutParams)viewRedPoint.getLayoutParams();
layoutparams.leftMargin=len; //设置左边距
viewRedPoint.setLayoutParams(layoutparams);//重新为小圆点设置边距
}
@Override
public void onPageSelected(int arg0) { //选中变化
if(arg0==mImageIds.length-1)
{
btnstart.setVisibility(View.VISIBLE);
}
else
{
btnstart.setVisibility(View.INVISIBLE);
}
}
}
class GuideAdapter extends PagerAdapter{
@Override
public int getCount() { // 得到图片的数量
// TODO Auto-generated method stub
return mImageIds.length;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) { //用来比较已存入的图片信息,进而当页面发生变化时,进行图片查找
// TODO Auto-generated method stub
return arg0==arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//把图片放入到container容器中。
container.addView(mImageViewList.get(position));
System.out.println("当前创建图片是: "+position);
return mImageViewList.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
System.out.println("destroy : "+position+" 图片!");
//销毁时,将页面删除掉
container.removeView((View) object);
//super.destroyItem(container, position, object);
}
}
}
/*
* 所有的点击变化都可以使用选择器selector进行设定
*/
相关文章推荐
- 排序算法小结
- 2-Fifteenth Scrum Meeting-20151215
- 301. Remove Invalid Parentheses
- VirtualBox的四种网络连接方式
- 硬盘内部硬件结构和工作原理详解
- Android中利用数据库查询电话归属地
- ExtJs——Ext基础架构--define定义一个类
- linux C++多线程编程介绍
- android开发之给LinearLayou设置网络图片作为背景
- 南工程操作系统原理期末复习
- html+css复习小结
- 密码
- 如何在Linux上部署gerrit 服务?
- 关于LinearLayout属性android:layout_marginRight的错误
- struts2学习笔记(三)
- MySQL安装--ubuntu
- leetcode -- Triangle -- dp题目重点
- 51nod贪心例子活动安排问题二
- 《多线程之GCD》
- storm入门教程 第一章 前言