仿百度壁纸客户端(三)——首页单向,双向事件冲突处理,壁纸列表的实现
2016-04-03 12:24
375 查看
仿百度壁纸客户端(三)——首页单向,双向事件冲突处理,壁纸列表的实现
百度壁纸系列
仿百度壁纸客户端(一)——主框架搭建,自定义Tab + ViewPager + Fragment仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图
仿百度壁纸客户端(三)——首页单向,双向事件冲突处理,壁纸列表的实现
仿百度壁纸客户端(四)——自定义上拉加载实现精选壁纸墙
仿百度壁纸客户端(五)——实现搜索动画GestureDetector手势识别,动态更新搜索关键字
仿百度壁纸客户端(六)——完结篇之Gallery画廊实现壁纸预览已经项目细节优化
上回把广告轮播图给实现了,今天就来把主页的大部分功能给实现了
一.ScrollView和ViewPager滑动事件冲突的解决办法
我们仔细想想,我们的主页架构,首先他是上下滑动的,所以这样要一个ScrollView,然后就是轮播图和其他内容了,这样的话,上下滑动有事件,轮播图也有事件,我们先看下xml的实现原理home_fragment_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"> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.lgl.baiduwallpaper.view.VPScrollLayout android:id="@+id/vp_scroll" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/vp_scroll" android:text="其他内容" android:textSize="50dp" /> </RelativeLayout> </ScrollView> </RelativeLayout>
這裡很清晰的可以看出层级关系了,他事件冲突时必然的,解决办法也是很简单,就单以这个架构来讲的话,其实只要判断他是上下滑动还是左右滑动就好,如果是左右滑动,就不给ScrollView传递事件了,如果是上下滑动的话,让ScrollView自身来处理了,所以我们需要重写ScrollView
DisScrollView
package com.lgl.baiduwallpaper.view; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ScrollView; /** * 事件冲突解决 * Created by lgl on 16/4/3. */ public class DisScrollView extends ScrollView { //手指按下的开始坐标 private float startX, startY; //手指移动的移动坐标 private float currentX, currentY; //手指抬起的最后坐标 private float endX, endY; //手指按下后的移动距离 private float distanceX,distanceY; /** * 构造方法 * * @param context * @param attrs */ public DisScrollView(Context context, AttributeSet attrs) { super(context, attrs); } /** * 事件分发 * * @param ev * @return */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { return super.dispatchTouchEvent(ev); } /** * 事件拦截 * * @param ev * @return */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { //按下事件 case MotionEvent.ACTION_DOWN: //获取坐标 startX = ev.getX(); startY = ev.getY(); break; //移动事件 case MotionEvent.ACTION_MOVE: //获取坐标 currentX = ev.getX(); currentY = ev.getY(); distanceX += Math.abs(currentX - startX); distanceY += Math.abs(currentY - startY); startX = currentX; startY = currentY; //判断滑动方向 if(distanceX >distanceY){ //左右滑动, //不拦截事件 return false; } break; } //上下移动自身处理 return super.onInterceptTouchEvent(ev); } }
OK,我们运行一下
关键是把逻辑处理好
二.GridView实现壁纸列表
1.ScrollView和GridView事件冲突
我们可以看看百度壁纸的效果,我们也来实现一下我们要实现的就是下面的一个壁纸列表,这里我们就要考虑一下了,怎么去实现,实际上,不管是ScrollView还是GridView他们都是内存超出屏幕才回去执行滑动事件,这样的话,我们自定义一个GridView把高直接写好就可以了
DisGridView
package com.lgl.baiduwallpaper.view; import android.content.Context; import android.util.AttributeSet; import android.widget.GridView; /** * 事件冲突 * Created by lgl on 16/4/3. */ public class DisGridView extends GridView { /** * 事件冲突 * * @param context * @param attrs */ public DisGridView(Context context, AttributeSet attrs) { super(context, attrs); } /** * View的测量,获得页面的整体尺寸 * * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, height); } }
然后我们就可以写布局了
home_fragment.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"> <com.lgl.baiduwallpaper.view.DisScrollView android:id="@+id/disScroolView" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.lgl.baiduwallpaper.view.VPScrollLayout android:id="@+id/vp_scroll" android:layout_width="match_parent" android:layout_height="wrap_content" /> <com.lgl.baiduwallpaper.view.DisGridView android:horizontalSpacing="10dp" android:verticalSpacing="10dp" android:numColumns="2" android:id="@+id/gridview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/vp_scroll" /> </RelativeLayout> </com.lgl.baiduwallpaper.view.DisScrollView> </RelativeLayout>
现在触摸事件已经OK了
2.实现壁纸列表
这里我们没有借口,就使用本地的壁纸了,但是完全都是按照网络请求操作来的,这里使用的解析图片的开源看是SmartImageView开源地址:https://github.com/loopj/android-smart-image-view
既然要使用GridView,那就必须要有一个实体类和一个item吧
HomeGrid
package com.lgl.baiduwallpaper.entity; /** * GridView数据实体类 * Created by lgl on 16/4/3. */ public class HomeGrid { /** * 当我们开发的时候,这里应该是个接口,那应该是String类型 * 我们现在模拟的是本地的图片,所以是int */ public HomeGrid(){ super(); } public HomeGrid(String type, int img) { this.type = type; this.img = img; } private int img; //描述 private String type; public int getImg() { return img; } public void setImg(int img) { this.img = img; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public String toString() { return "HomeGrid{" + "img=" + img + ", type='" + type + '\'' + '}'; } }
grid_item.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="200dp" android:orientation="vertical"> <com.loopj.android.image.SmartImageView android:id="@+id/mySmartImageView" android:layout_width="wrap_content" android:layout_height="match_parent" /> <TextView android:id="@+id/tv_nice" android:layout_width="match_parent" android:layout_height="40dp" android:layout_alignParentBottom="true" android:alpha="0.3" android:background="#000" android:gravity="left|center_vertical" android:paddingLeft="15dp" android:textColor="#fff" android:textSize="16sp" /> </RelativeLayout>
然后我们回到HomeFragment中,我们定义一个方法initGridData
/** * 初始化GridView的数据 */ private void initGridData() { for (int i = 0; i < 10; i++) { HomeGrid grid = new HomeGrid(); grid.setImg(R.drawable.nice); grid.setType("美女"); gridData.add(grid); } }
现在可以定义一个adapter了
/** * GridView的adapter */ private class GridViewAdapter extends BaseAdapter { private Context context; private LayoutInflater inflater; /** * 构造方法 * * @param context */ public GridViewAdapter(Context context) { this.context = context; inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return gridData.size(); } @Override public Object getItem(int position) { return gridData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; //第一次加载 if (convertView == null) { convertView = inflater.inflate(R.layout.grid_item, null); viewHolder = new ViewHolder(); viewHolder.img = (SmartImageView) convertView.findViewById(R.id.mySmartImageView); viewHolder.tv = (TextView) convertView.findViewById(R.id.tv_nice); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } // viewHolder.img.setImageResource(gridData.get(position).getImg()); viewHolder.img.setBackgroundResource(gridData.get(position).getImg()); viewHolder.tv.setText(gridData.get(position).getType()); //动态设置高度 convertView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,300)); return convertView; } } private static class ViewHolder { private SmartImageView img; private TextView tv; }
写到这里,基本上就可以看到效果了
但是还是有一些细节需要处理的,比图scroolview一进来需要回滚到第一行
//设置每次进入现最前面 disScroolView.smoothScrollTo(0,0);
看代码应该就能看的很清晰了吧,我们来演示一下
有一点小粗糙,这就需要各位自己去完善了
三.意见反馈
我们滑动到最后会发现,有一个意见反馈,我们去实现它在这里我们先不做跳转,先只是十点他的点击效果吧,也是相当点击简单,我们只要在DisGridView加上一个布局
<RelativeLayout android:clickable="true" android:background="@drawable/bottom_select" android:layout_below="@+id/gridview" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_centerInParent="true" android:gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:src="@drawable/image_more_icon_feedback" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_marginLeft="5dp" android:text="意见反馈" android:textSize="18sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </RelativeLayout>
就可以了,这里我们还要实现它的点击效果
bottom_select.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/image_more_subitems_bottom_selected" android:state_enabled="true" android:state_pressed="true"></item> <item android:drawable="@drawable/image_more_subitems_bottom_selected" android:state_pressed="true"></item> <item android:state_pressed="false" android:drawable="@drawable/image_more_subitems_bottom"></item> </selector>
让我们来运行一下吧
这里我把完整的HomeFragment贴上,就不上传源码了
HomeFragment
package com.lgl.baiduwallpaper.fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.lgl.baiduwallpaper.R;
import com.lgl.baiduwallpaper.entity.HomeGrid;
import com.lgl.baiduwallpaper.view.DisGridView;
import com.lgl.baiduwallpaper.view.DisScrollView;
import com.lgl.baiduwallpaper.view.VPScrollLayout;
import com.loopj.android.image.SmartImageView;
import java.util.ArrayList;
/**
* 主页
* Created by lgl on 16/3/31.
*/
public class HomeFragment extends Fragment {
private VPScrollLayout vpScroll;
private ViewPager myViewPager;
private ArrayList<View> bitmap = new ArrayList<View>();
private DisGridView mGridView;
private ArrayList<HomeGrid> gridData = new ArrayList<HomeGrid>();
private DisScrollView disScroolView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);
findView(view);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
init();
}
/**
* 初始化
*/
private void init() {
initVPData();
initGridData();
myViewPager.setAdapter(new MyAdapter());
//设置几秒轮播
vpScroll.setPagerFromTime(1000);
//设置adapter
mGridView.setAdapter(new GridViewAdapter(getActivity()));
//设置每次进入现最前面 disScroolView.smoothScrollTo(0,0);
}
/**
* 初始化GridView的数据
*/
private void initGridData() {
for (int i = 0; i < 10; i++) {
HomeGrid grid = new HomeGrid();
grid.setImg(R.drawable.nice);
grid.setType("美女");
gridData.add(grid);
}
}
/**
* 初始化图片
*/
private void initVPData() {
LayoutInflater inflater1 = getActivity().getLayoutInflater();
View view1 = inflater1.inflate(R.layout.vp_seroll_item, null);
view1.findViewById(R.id.vpImg).setBackgroundResource(R.mipmap.img1);
bitmap.add(view1);
LayoutInflater inflater2 = getActivity().getLayoutInflater();
View view2 = inflater2.inflate(R.layout.vp_seroll_item, null);
view2.findViewById(R.id.vpImg).setBackgroundResource(R.mipmap.img2);
bitmap.add(view2);
LayoutInflater inflater3 = getActivity().getLayoutInflater();
View view3 = inflater3.inflate(R.layout.vp_seroll_item, null);
view3.findViewById(R.id.vpImg).setBackgroundResource(R.mipmap.img3);
bitmap.add(view3);
LayoutInflater inflater4 = getActivity().getLayoutInflater();
View view4 = inflater4.inflate(R.layout.vp_seroll_item, null);
view4.findViewById(R.id.vpImg).setBackgroundResource(R.mipmap.img4);
bitmap.add(view4);
}
/**
* 绑定
*
* @param view
*/
private void findView(View view) {
vpScroll = (VPScrollLayout) view.findViewById(R.id.vp_scroll);
//直接拿到
myViewPager = vpScroll.getViewPager();
mGridView = (DisGridView) view.findViewById(R.id.gridview);
disScroolView = (DisScrollView) view.findViewById(R.id.disScroolView);
}
/**
* adapter
*/
private class MyAdapter extends PagerAdapter {
@Override
public int getCount() {
return bitmap.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
//删除
((ViewPager) container).removeView(bitmap.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
((ViewPager) container).addView(bitmap.get(position));
return bitmap.get(position);
}
}
/** * GridView的adapter */ private class GridViewAdapter extends BaseAdapter { private Context context; private LayoutInflater inflater; /** * 构造方法 * * @param context */ public GridViewAdapter(Context context) { this.context = context; inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return gridData.size(); } @Override public Object getItem(int position) { return gridData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; //第一次加载 if (convertView == null) { convertView = inflater.inflate(R.layout.grid_item, null); viewHolder = new ViewHolder(); viewHolder.img = (SmartImageView) convertView.findViewById(R.id.mySmartImageView); viewHolder.tv = (TextView) convertView.findViewById(R.id.tv_nice); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } // viewHolder.img.setImageResource(gridData.get(position).getImg()); viewHolder.img.setBackgroundResource(gridData.get(position).getImg()); viewHolder.tv.setText(gridData.get(position).getType()); //动态设置高度 convertView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,300)); return convertView; } } private static class ViewHolder { private SmartImageView img; private TextView tv; }
}
好了,我们首页就已经做好了,是不是非常的简单尼?在我们的分析之后,其实这个软件也就那么回事哈
Demo下载地址:http://download.csdn.net/detail/qq_26787115/9480171
相关文章推荐
- Android课程---单选框与复选框的实现
- c++中动态尾随内存的技巧和定位new
- SAS学习笔记:创建图表
- create samba server
- jquery中attr和prop的区别
- 理解Cookie和Session机制
- Exception starting filter Struts2
- 开源的相关记录
- Android编译详解之lunch命令
- webdriver中Xpath当前节点寻找父节点下的字节点
- 工厂模式和策略模式的区别
- JAVA反射机制
- HashMap 原理和源码分析
- nginx记录响应与POST请求日志
- nginx记录响应与POST请求日志
- 应用"新特性"功能demo
- 搜狐视频Redis私有云平台CacheCloud
- Android课程---计算器的实现
- [南极星]何处是归处
- [置顶] 科大讯飞语音集成,非常详细的使用讲解