仿百度壁纸客户端(四)——自定义上拉加载实现精选壁纸墙
百度壁纸系列
仿百度壁纸客户端(一)——主框架搭建,自定义Tab + ViewPager + Fragment
仿百度壁纸客户端(二)——主页自定义ViewPager广告定时轮播图
仿百度壁纸客户端(三)——首页单向,双向事件冲突处理,壁纸列表的实现
主页说完了,我们来实现第二个页面吧,第二个精选其实就是一个壁纸墙,百度壁纸本身也没做下拉刷新,所以我们只考虑上拉加载,其实实现不负责,壁纸墙还是用主页的自定义GridView,但是这里我们还得重写ScroolView来监听他是否滑动到底部,这样吧,我们先来看一下百度壁纸的效果吧:
我们先来自定义一个ScrollView监听滑动到底部
PullScrollView
package com.lgl.baiduwallpaper.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
/**
* 刷新的View,主要是监听是否滑动到顶部或者底部
* Created by lgl on 16/4/6.
*/
public class PullScrollView extends ScrollView {
private static final String LOAD = "load";
public IcallBack icallBack = null;
//构造方法
public PullScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 手指滑动,不停的调用
* @param l
* @param t
* @param oldl
* @param oldt
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
check();
super.onScrollChanged(l, t, oldl, oldt);
}
/**
* 上下监听
*/
private void check() {
//判断是否上拉到底部
if (getChildAt(0) != null && getChildAt(0).getMeasuredHeight() <= getScrollY() + getHeight()) {
if(LoadReshView.getBottomOrTop()){
return;
}
//回调到下一个页面
icallBack.click(LOAD);
}
}
/**
* 定义一个底部的接口
*/
public interface IcallBack {
public void click(String bottom);
}
/**
* 定义一个方法
*/
public void setIcallBack(IcallBack icallBack) {
this.icallBack = icallBack;
}
}
这里我们就可以写一个组合控件了,把具体功能给全部实现的控件了,我们先定义这样的一个布局
pull_load.xml
<?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">
<com.lgl.baiduwallpaper.view.PullScrollView
android:id="@+id/pull_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.lgl.baiduwallpaper.view.DisGridView
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
android:numColumns="3"
android:id="@+id/mGridView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal">
<!--加载更多的进度-->
<ProgressBar
android:id="@+id/proBar"
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载..." />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</com.lgl.baiduwallpaper.view.PullScrollView>
</LinearLayout>
那我们就来实现了,我们自定义一个容器
LoadReshView
package com.lgl.baiduwallpaper.view;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import com.lgl.baiduwallpaper.R;
/**
* 上啦 刷新
* Created by lgl on 16/4/6.
*/
public class LoadReshView extends LinearLayout {
private static final String LOAD = "load";
private static final int LOADDATA = 1;
private static final int REFREAH = 2;
//监听底部
private PullScrollView pullScrollView;
//数据表格
private DisGridView mGridView;
//下拉显示布局
private LinearLayout linearLayout;
public pullCallBack pull = null;
//没有显示底部布局
private static boolean isShow = false;
/**
* 子线程
*/
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case LOADDATA:
isBottomShow();
isShow = true;
break;
case REFREAH:
isBottomSClose();
isShow = false;
break;
}
super.handleMessage(msg);
}
};
/**
* 构造方法
*
* @param context
* @param attrs
*/
public LoadReshView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
/**
* 初始化
*/
private void initView() {
//加载布局文件
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.pull_load, this);
findView(view);
setCallBack();
}
/**
* 实现回调接口
*/
private void setCallBack() {
pullScrollView.setIcallBack(new MyIcallback());
}
/**
* 实现接口
*/
private class MyIcallback implements PullScrollView.IcallBack {
@Override
public void click(String bottom) {
//如果监听到最底部
if (bottom.equals(LOAD)) {
pull.load();
//显示
handler.sendEmptyMessage(LOADDATA);
} else {
pull.reFresh();
}
}
}
/**
* 加载数据的接口
*/
public interface pullCallBack {
//加載
public void load();
//刷新
public void reFresh();
}
/**
* 初始化控件
*
* @param view
*/
private void findView(View view) {
pullScrollView = (PullScrollView) view.findViewById(R.id.pull_scroll);
mGridView = (DisGridView) view.findViewById(R.id.mGridView);
linearLayout = (LinearLayout) view.findViewById(R.id.linearLayout);
}
public void setpullCallBack(pullCallBack pull) {
this.pull = pull;
}
/**
* 判斷是否显示操作
*
* @return
*/
public static boolean getBottomOrTop() {
return isShow;
}
/**
* 显示底部
*/
public void isBottomShow() {
linearLayout.setVisibility(View.VISIBLE);
}
public void isBottomSClose() {
linearLayout.setVisibility(View.GONE);
}
/**
* 数据加载完成
*/
public void dataFinish() {
handler.sendEmptyMessage(REFREAH);
}
/**
* 返回
*
* @return
*/
public PullScrollView getpullScrollView() {
return pullScrollView;
}
/**
* 返回
*
* @return
*/
public DisGridView getGridView() {
return mGridView;
}
}
这里我们就可以去实现这个功能了,GridView需要一个adapter,那就要一个item,也就是一个imageview(实际项目中,是使用smartimageview)的
sele_item.xml
<?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">
<ImageView
android:id="@+id/smartimg"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
最后,我们就可以来实现精选页SelectFragment的逻辑了
SelectFragment
package com.lgl.baiduwallpaper.fragment;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.lgl.baiduwallpaper.R;
import com.lgl.baiduwallpaper.view.DisGridView;
import com.lgl.baiduwallpaper.view.LoadReshView;
import java.util.ArrayList;
/**
* 精选
* Created by lgl on 16/3/31.
*/
public class SelectFragment extends Fragment {
private LoadReshView loadview;
private DisGridView myGridView;
private ArrayList<Integer> data = new ArrayList<Integer>();
private myAdapter adapter;
private Handler handle= new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 100:
adapter.notifyDataSetChanged();
loadview.dataFinish();
break;
}
super.handleMessage(msg);
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.select_fragment, container, false);
findView(view);
return view;
}
/**
* 初始化控件
*
* @param view
*/
private void findView(View view) {
loadview = (LoadReshView) view.findViewById(R.id.myloadview);
// myGridView = (DisGridView) view.findViewById(R.id.mGridView);
myGridView = loadview.getGridView();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
init();
}
/**
* 初始化数据
*/
private void init() {
loadview.setpullCallBack(new PullClick());
initGridData();
adapter = new myAdapter(getActivity());
myGridView.setAdapter(adapter);
}
/**
* GridView数据
*/
private void initGridData() {
for (int i = 0; i < 10; i++) {
//添加数据
data.add(R.drawable.nice);
}
}
private class PullClick implements LoadReshView.pullCallBack {
//加载数据
@Override
public void load() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//睡一下
Thread.sleep(2000);
initGridData();
handle.sendEmptyMessage(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
//刷新数据
@Override
public void reFresh() {
}
}
/**
* GridView的Adapter
*/
private class myAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater inflater;
public myAdapter(Context mContext) {
this.mContext = mContext;
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.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.sele_item, null);
viewHolder = new ViewHolder();
viewHolder.imgs = (ImageView) convertView.findViewById(R.id.smartimg);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//设置数据
convertView.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,300));
viewHolder.imgs.setBackgroundResource(R.drawable.nice);
return convertView;
}
}
static class ViewHolder {
ImageView imgs;
}
}
最后的运行效果
这个虽然有些粗糙,但是我们主要还是实现逻辑为主,UI部分大家自行调整哈