#
scrollView
viewpager
fragment
handler 快速搜索
开源项目 slidingmenuhm
左滑 右滑 interceptTouchEvent拦截事件
☆☆☆☆☆去标题栏
// 在onCreate中 去掉标题栏 调用方法
// requestWindowFeature(Window.FEATURE_NO_TITLE);
去掉标题栏
全屏时需要同时加下面的两个item
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:windowFullscreen">true</item>
<item name="android:windowNoTitle">true</item>
<!-- API 14 theme customizations can go here. -->
</style>
iv.setBackgroundResource(picture[i]);//填充背景窗口
iv.setImageResource(picture[i]);//显示的是图片实际的大小
☆☆☆☆☆ViewGroup
继承ViewGroup 需要重新测量,看布局宽和高的值
/*@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//如果布局的宽和高是固定的值 设置measureChildren(0,0);否则 measureChildren(widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}*/
☆☆☆☆☆ViewGroup
自定义的类继承了RelativeLayout 不需要再次测量onmeasure();和排版onLayout();
ViewPager使用 实现图片无限循环播放
public class MainActivity extends Activity {
private int[] picture = new int[] { R.drawable.icon_1, R.drawable.icon_2,
R.drawable.icon_3, R.drawable.icon_4, R.drawable.icon_5 };
private String[] descs = { "为梦想坚持", "我相信我是黑马", "黑马公开课", "Google/IO",
"轻松1w+" };
private ArrayList<ImageView> list;// ImageView 图片
private ArrayList<View> dots;// View 小黑点
private ViewPager pager;
private TextView tv_content;
private LinearLayout ll_layout;
private View currentView;
/** 用handler实现自动滚动 **/
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
// 显示下一个图片
pager.setCurrentItem(pager.getCurrentItem() + 1);
// 再次发送,实现无限滚动
handler.sendEmptyMessageDelayed(10, 3500);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 去掉标题栏
// requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
/** 初始化数据 **/
initData();
/** 初始化adapter **/
initAdapter();
/** 设置pager滚动监听的事件 **/
pager.setOnPageChangeListener(new Listen());
}
/** 屏幕可见时 实现自动滚动图片 **/
@Override
protected void onStart() {
// 参数1:是标记 参数2:间隔时间
handler.sendEmptyMessageDelayed(10, 3500);
super.onStart();
}
/** 屏幕不可见时 关闭自动滚动图片 **/
@Override
protected void onStop() {
// 10 用于识别handler,作为标记
handler.removeMessages(10);
super.onStop();
}
/** 设置pager滚动监听的事件 **/
public class Listen implements OnPageChangeListener {
// 滚动
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
// 当一个新的页面被选中的时候调用
@Override
public void onPageSelected(int position) {
// 小圆点和内容的改变 封装成方法,方便调用
dot_contentChange(position);
}
// 当滑动页面的状态改变的时候调用
@Override
public void onPageScrollStateChanged(int state) {
}
}
/** 小圆点和内容的改变 封装成方法,方便调用 **/
private void dot_contentChange(int position) {
// [1]动态改变小圆点的文本内容 数据在哪里存着就去哪里取
tv_content.setText(descs[position % 5]);
View dot = dots.get(position % 5);
if (currentView != null) {
currentView.setSelected(false);
}
// [2]更新小圆点的状态 小圆点在集合里面存着
dot.setSelected(true);
// [3]把dots.get(position % 5)赋值给currentView
currentView = dot;
}
/** 初始化adapter **/
private void initAdapter() {
pager.setAdapter(new MyPagerAdapter());
// 加载设置 实现既可以往左滑又可以往右滑
pager.setCurrentItem(1000000000 / 2);
}
/** 初始化数据 **/
private void initData() {
// viewpager控件
pager = (ViewPager) findViewById(R.id.viewpager1);
// 显示的文本内容
tv_content = (TextView) findViewById(R.id.tv_content);
ll_layout = (LinearLayout) findViewById(R.id.ll_layout);
// 显示小黑点
list = new ArrayList<ImageView>();
dots = new ArrayList<View>();
for (int i = 0; i < picture.length; i++) {
ImageView iv = new ImageView(getApplicationContext());
iv.setBackgroundResource(picture[i]);
// 显示的是图片实际的大小
// iv.setImageResource(picture[i]);
list.add(iv);
}
/** 初始化小黑点 自己绘制加参数 **/
for (int i = 0; i < picture.length; i++) {
// [1]初始化小圆点的view
View view = new View(getApplicationContext());
// [2]设置dotView宽和高
LayoutParams params = new LayoutParams(7, 7);
params.bottomMargin = 10;
if (i != 0) {
params.leftMargin = 7;
}
view.setLayoutParams(params);
view.setBackgroundResource(R.drawable.dot_selector);
ll_layout.addView(view);
dots.add(view);
}
// 初始化数据时将第一张的文字和小圆点选中
dot_contentChange(0);
}
/** 初始化adapter **/
public class MyPagerAdapter extends PagerAdapter {
/** 返回一个极大值实现无限循环 **/
@Override
public int getCount() {
// return list.size();
return 1000000000;
// return Integer.MAX_VALUE;
}
/**
* Object:就是在instantiateItem方法里面返回的内容
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/**
* 初始化条目的内容 类似lsitview getView方法 container:就是viewPager
* position:每个页面的对应的位置
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = list.get(position % 5);
container.addView(imageView);
return imageView;
}
/**
* 移除不用的页面 container:viewPager object:就是instantiateItem方法里面的返回值
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
侧滑菜单
功能分析:实际上是两个页面 通过一个viewGroup进行包裹
menu菜单实际上就是一个scrollView包裹了一个垂直的线性布局,scrollView只能包裹一个孩子.
[1]搭建页面 大家主页面 和 菜单页面
主页面布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/top_bar_bg"
android:orientation="horizontal" >
<Button
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/main_back" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="3dp"
android:src="@drawable/top_bar_divider" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:text="黑马新闻"
android:textColor="#ffffff"
android:textSize="25sp" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="钓鱼岛是中国的,\nXXX是世界的"
android:gravity="center"
android:textSize="25sp" />
</LinearLayout>
菜单页面布局
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="240dp"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="240dp"
android:layout_height="match_parent"
android:background="@drawable/menu_bg"
android:orientation="vertical" >
<TextView
style="@style/MenuText"
android:background="#571F2C"
android:drawableLeft="@drawable/tab_news"
android:text="新闻" />
<TextView
style="@style/MenuText"
android:drawableLeft="@drawable/tab_read"
android:text="订阅" />
<TextView
style="@style/MenuText"
android:drawableLeft="@drawable/tab_ties"
android:text="跟帖" />
<TextView
style="@style/MenuText"
android:drawableLeft="@drawable/tab_pics"
android:text="图片" />
<TextView
style="@style/MenuText"
android:drawableLeft="@drawable/tab_ugc"
android:text="话题" />
<TextView
style="@style/MenuText"
android:drawableLeft="@drawable/tab_vote"
android:text="投票" />
<TextView
style="@style/MenuText"
android:drawableLeft="@drawable/tab_focus"
android:text="聚合阅读" />
</LinearLayout>
</ScrollView>
[2]定义一个viewGroup (slidingMenu) 把我们刚刚定义的布局加到slidingMenu里面
<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=".MainActivity" >
<com.itheima.slidingmenuhm.SlidingMenu
android:id="@+id/slidingMenu1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- 添加自己的孩子 menu菜单和main主界面 -->
<include layout="@layout/menu" />
<include layout="@layout/main" />
</com.itheima.slidingmenuhm.SlidingMenu>
</RelativeLayout>
[3]由于我定义的slidingmenu继承自相对布局 系统默认实现了测量和排版 所以不需要我们在进行测量 但是我们需要排版,因为系统的排版方式不是我们想要的 所以我们自己重写onLayout方法对孩子进行排版
//在这个方法里面 自己对孩子进行排版 不使用系统默认的排版方式
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//[1]找到menu和main孩子
View menuView = getChildAt(0);
View mainView = getChildAt(1);
//[2]获取菜单的宽度
menuWidth = menuView.getMeasuredWidth();
//[3]对menu菜单进行排版
menuView.layout(-menuWidth, t, l, b);
//[4]对main界面排版
mainView.layout(l, t, r, b);
}
[4]当用户手指滑动的时候 算出移动的距离 让菜单滑出来 需要我们重写OnTouchEvent方法处理事件
case MotionEvent.ACTION_DOWN: //按下
//[1]获取手指按下的坐标
downX = event.getX();
break;
case MotionEvent.ACTION_MOVE: //移动
//[2]算出移动的距离
float moveX = event.getX();
distaceX = (int) (moveX - downX)+currentMenuPosition;
//[3]对边界进行处理
if (distaceX <= 0) {
distaceX = 0;
}else if (distaceX >=menuWidth) {
distaceX = menuWidth;
}
//[4]开始滚动view
startScrollViewContent(distaceX);
break;
[5]我们自己定义了一个view滚动的方法 让view 的内容进行滚动 因为系统的ScrollTo方法不好用
/**
* 由于scrollTo 方法 系统在实现的时候 传入正值往左移动 传入负值往右移动 所以我重写这个方
* 符合中国 人的思维
* @param x
*/
public void startScrollViewContent(int x){
super.scrollTo(-x, 0);
}
[6]处理手指抬起的逻辑 ,当移动的距离<菜单的宽/2 就让菜单回到0 否则把菜单全部显示
case MotionEvent.ACTION_UP: //抬起
//[5]当手指抬起后, 如果移动的距离 < 菜单的宽/2 就回到左边 否则像右移动
if (distaceX < menuWidth/2) {
currentMenuPosition = 0;
}else {
currentMenuPosition = menuWidth;
}
//[6]当一段逻辑同时用到多次 我们最好做抽取
int startX = distaceX; //就是移动的距离
int endX = currentMenuPosition;
//[7]实现平滑滚动
startScroller(startX, endX);
break;
[7]当menu菜单打开后,我在菜单上向左滑动 发现不能滑动,因为孩子消费了事件,所以我们在slidingmenu(viewGroup)里的onInterceptTouchevent里面处理事件(拦截事件).
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = ev.getX();
downY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float moveX = ev.getX();
float moveY = ev.getY();
//[1]算出X轴移动的距离 和 Y移动的距离
int distanceX = (int) (moveX - downX);
int distanceY = (int) (moveY - downY);
//[2]如果x轴移动的距离大于Y轴移动的距离 就拦截事件
if (Math.abs(distanceX) > Math.abs(distanceY)) {
return true;
}
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);
}
[8]点击主页面的按钮判断菜单是否打开或者关闭
//通过这个方法控制菜单打开或者关闭
public void setOnMenuIsOpen() {
int startX = 0;
if (currentMenuPosition == 0) {
//说明菜单是关闭状态 需要打开
currentMenuPosition = menuWidth;
}else if (currentMenuPosition == menuWidth) {
//说明菜单是打开状态 需要关闭
currentMenuPosition = 0;
startX = menuWidth;
}
//调用平滑滚动的方法
startScroller(startX, currentMenuPosition);
}
2 广告条效果
使用viewpager实现 直接放到了v4包里,fragment
viewpager直接继承ViewGroup 需要往viewpager里面添加孩子.
viewpager可以让用户左右滑动 和listview相反
viewpager展示数据的原理和listview一样, 使用自己的适配器展示数据(pagerAdapter)
使用的步骤
[1]在布局里面声明viewpager
<android.support.v4.view.ViewPager
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="180dp" >
</android.support.v4.view.ViewPager>
[2]关联 v4包的源码
2.1)在libs下创建一个android-support-v4.jar.properties配置文件
2.2)配置文件里面的代码如下
src=D:\\Android\\adt-bundle-windows-x86_64_20140101\\sdk\\extras\\android\\support\\v4\\src
2.3)关闭工程在打开工程即可
[3]创建viewpager的适配器
//创建viewpager需要的适配器
class MyPagerAdapter extends PagerAdapter{
//展示viewpager条目的数量
@Override
public int getCount() {
return ivs.size();
}
/**
* Object:就是在instantiateItem方法里面返回的内容
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/**
* 初始化条目的内容 类似lsitview getView方法
* container:就是viewPager
* position:每个页面的对应的位置
*/
@Override
public Object instantiateItem(ViewGroup container, int position) {
//[1]根据位置 去集合里面取数据
ImageView iv = ivs.get(position);
//[2]获取到每个iv后加入到viewpager中
container.addView(iv);
return iv;
}
/**
* 移除不用到页面
* container:viewPager
* object:就是instantiateItem方法里面的返回值
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
[4]添加小圆点的布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/vp"
android:background="#66000000"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingTop="5dp" >
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是小圆点对应的内容"
android:textColor="#ffffff"
android:textSize="17sp" />
<!-- 动态的往布局里面添加小圆点 -->
<LinearLayout
android:id="@+id/ll_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:orientation="horizontal" >
<!-- <View
android:layout_width="5dp"
android:layout_height="5dp"
android:background="@drawable/dot_selector" /> -->
</LinearLayout>
</LinearLayout>
[5]给viewpager设置页面滚动的监听
//代表viewpager的监听
OnPageChangeListener listener = new OnPageChangeListener() {
//当一个新的页面被选中的时候调用
@Override
public void onPageSelected(int position) {
changeDotstateAndText(position);
}
//当页面开始滚动
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
//当滑动页面的状态改变的时候调用
@Override
public void onPageScrollStateChanged(int state) {
}
};
[6]动态改变小圆点状态和对应文本的内容 由于2个地方都需要改变小圆点的状态和对应的内容 所以我们抽出一个方法
/**改变小圆点的状态和对应文本的内容**/
private void changeDotstateAndText(int position) {
//[1]动态改变小圆点的文本内容 数据在哪里存着就去哪里取
tv_content.setText(descs[position]);
if (currentDotView!=null) {
currentDotView.setSelected(false);
}
//[2]更新小圆点的状态 小圆点在集合里面存着
dotLists.get(position).setSelected(true);
//[3]把dotLists.get(position)赋值给currentDotView
currentDotView = dotLists.get(position);
}
[7]实现viewpager的无限循环
0 % 5 = 0
1 % 5 = 1
2 %5 =2
3 %5=3;
4%5=4
5%5 = 0
6%5 = 1
7%5=2 .......
就是在适配器的getcount方法里面返回一个比较大的数就可以了 把position对5取%
[8]实现自动切换
在onStart方法里面使用handler发一个消息
//当界面可见的时候执行
@Override
protected void onStart() {
//4秒钟后 显示下一个页面的内容
handler.sendEmptyMessageDelayed(10, 4000);
super.onStart();
}
在handlermessage方法里面处理消息
private Handler handler = new Handler(){
//处理消息
public void handleMessage(android.os.Message msg) {
//显示viewpager下个页面的内容
vp.setCurrentItem(vp.getCurrentItem()+1);
handler.sendEmptyMessageDelayed(10, 4000);
};
};
[9]当viewpager初始化的时候既可以往左滑动,又可以往又滑动
1.vp.setCurrentItem(vpMaxSize/2);
作者:yin13753884368 发表于2016/11/18 20:12:00 原文链接
阅读:35 评论:0 查看评论