最近电商类项目有个需求挺头疼,要求用GridView去显示商品,滑动到底部下拉能加载更多商品,向下滑动过程中需要隐藏掉自定义的Action布局,向上滑动能显示出来,整体效果类似淘宝APP搜索结果页那样。

起初觉得挺简单的,但是后来才发现还是得转一点脑子。最开始我想用PullToRefreshGridView,但是后来发现GridView没有添加headview的方法,只能采用PullToRefreshScrollView内嵌套GridView的方法,Scrollview里多放一个空白布局当GridView的headview,高度和Action布局一样就行。这时还有一个问题,ScrollView和GridView会产生滑动冲突,还好网上很容易找到解决办法,我这里采用自定义GridView,最后就是监听方法了,最为关键的点,还是直接上代码吧:


自定义GridView:

package com.example.ztestscrollview;


import android.content.Context;

import android.util.AttributeSet;

import android.view.View.MeasureSpec;

import android.widget.GridView;


public class MyGridView extends GridView{

public MyGridView(Context context, AttributeSet attrs) {

super(context, attrs);

}

public MyGridView(Context context) {

super(context);

}

public MyGridView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

}

@Override

public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,

MeasureSpec.AT_MOST);

super.onMeasure(widthMeasureSpec, expandSpec);

}

}




主界面:

package com.example.ztestscrollview;


import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

import android.view.Menu;

import android.view.MotionEvent;

import android.view.View;

import android.view.View.OnTouchListener;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ScrollView;


import com.handmark.pulltorefresh.library.PullToRefreshBase;

import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;

import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;

import com.handmark.pulltorefresh.library.PullToRefreshScrollView;


public class MainActivity extends Activity

{


int num = 10;

private GridAdapter adapter;

private ScrollView scrollView;

private PullToRefreshScrollView ptr_scrollview;

private View actionLayout;

private MyGridView myGridview;


@Override

protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


actionLayout = findViewById(R.id.actionlayout);


ptr_scrollview = (PullToRefreshScrollView) findViewById(R.id.ptr_scrollview);

ptr_scrollview.setMode(Mode.PULL_UP_TO_REFRESH);

ptr_scrollview.setOnRefreshListener(new OnRefreshListener<ScrollView>()

{


@Override

public void onRefresh(PullToRefreshBase<ScrollView> refreshView)

{

num += 10;

adapter.notifyDataSetChanged();

ptr_scrollview.onRefreshComplete();

}

});


myGridview = (MyGridView) findViewById(R.id.myGridView1);

adapter = new GridAdapter();

myGridview.setAdapter(adapter);


scrollView = ptr_scrollview.getRefreshableView();

scrollView.setOnTouchListener(new OnTouchListener()

{

// 判断是否第一个滑动值

boolean isFirst = true;

// Scrollview滑动的ScrollY值

private int ScrollY_Move;

// 第一个滑动的ScrollY值

private int First_ScrollY_Move;

// 手指抬起时ScrollY值

private int ScrollY_Up;

// ScrollY_Move和First_ScrollY_Move的差值

private int Cha;


@Override

public boolean onTouch(View v, MotionEvent event)

{

switch (event.getAction())

{

//ACTIN_DOWN没用,不用监听

case MotionEvent.ACTION_MOVE:

if (isFirst)

{

// 记录下第一个滑动的ScrollY值

First_ScrollY_Move = v.getScrollY();

isFirst = false;

}

// 记录下Scrollview滑动的ScrollY值

ScrollY_Move = v.getScrollY();


// 计算出ScrollY_Move和First_ScrollY_Move的差值

Cha = ScrollY_Move - First_ScrollY_Move;


// 当ScrollY_Move>First_ScrollY_Move时证明滑动方向是向下;

// 加上判断差值的目的:当Actionbar显示的时候,手指按住往下滑过一段距离还未抬起时,Actionbar也能隐藏

if (First_ScrollY_Move < ScrollY_Move || Cha > 200)

{

// 隐藏Actionbar

actionLayout.setVisibility(View.GONE);

}


// 当ScrollY_Move<First_ScrollY_Move时证明滑动方向是向上;

// 加上判断差值的目的:当Actionbar显示的时候,手指按住往上滑过一段距离还未抬起时,Actionbar也能显示

// 判断ScrollY_Move < 150目的:当Scrollview滑动接近顶端时必须显示Actionbar

else if (First_ScrollY_Move > ScrollY_Move || Cha < -200

|| ScrollY_Move < 150)

{

actionLayout.setVisibility(View.VISIBLE);

}

break;

case MotionEvent.ACTION_UP:

ScrollY_Up = v.getScrollY();// 记录下手指抬起时ScrollY值

isFirst = true;// 将isFirst还原为初始化

if (ScrollY_Up == 0)

{

actionLayout.setVisibility(View.VISIBLE);

}

// Log.e("ACTION_UP--->", "scrollY_up:" + scrollY_up + " "

// + "eventY_up:" + eventY_up);


break;


default:

break;

}

return false;

}


});


}


class GridAdapter extends BaseAdapter

{

@Override

public View getView(int position, View convertView, ViewGroup parent)

{

View inflate = getLayoutInflater().inflate(R.layout.griditem, null);

return inflate;

}


@Override

public int getCount()

{

// TODO Auto-generated method stub

return num;

}


@Override

public Object getItem(int position)

{

// TODO Auto-generated method stub

return null;

}


@Override

public long getItemId(int position)

{

// TODO Auto-generated method stub

return 0;

}


}


@Override

public boolean onCreateOptionsMenu(Menu menu)

{

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true;

}


}



布局:

<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.handmark.pulltorefresh.library.PullToRefreshScrollView

android:id="@+id/ptr_scrollview"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_alignParentLeft="true"

android:layout_alignParentTop="true" >


<RelativeLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

android:descendantFocusability="blocksDescendants" >


<RelativeLayout

android:id="@+id/headview"

android:layout_width="match_parent"

android:layout_height="120dp"

android:layout_alignParentLeft="true"

android:layout_alignParentTop="true" >

</RelativeLayout>


<com.example.ztestscrollview.MyGridView

android:id="@+id/myGridView1"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_below="@+id/headview"

android:numColumns="2" >

</com.example.ztestscrollview.MyGridView>

</RelativeLayout>

</com.handmark.pulltorefresh.library.PullToRefreshScrollView>


<RelativeLayout

android:id="@+id/actionlayout"

android:layout_width="match_parent"

android:layout_height="120dp"

android:layout_alignParentLeft="true"

android:layout_alignParentTop="true"

android:background="#cdcdcd" >


<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:layout_centerVertical="true"

android:text="ActionLayout" />

</RelativeLayout>


</RelativeLayout>