首页 > 代码库 > PullToRefreshScrollView实现顶层搜索框 滑动可隐藏 下面刷自定义GridView

PullToRefreshScrollView实现顶层搜索框 滑动可隐藏 下面刷自定义GridView

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

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

一、自定义GridView,解决ScrollView嵌套GridView布局加载数据不全问题

package com.hospital.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;

/**
* Created by Achen on 2016/7/23.
*/
public class MyGridView extends GridView{
public MyGridView(Context context) {
super(context);
  }

public MyGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}


二、布局
父布局

<?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:background="@color/white"
android:orientation="vertical"    <LinearLayout
           android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/dimens_7_160"
android:layout_marginRight="@dimen/dimens_7_160"
android:layout_marginTop="@dimen/dimens_3_160">

       <com.handmark.pulltorefresh.library.PullToRefreshScrollView
        xmlns:ptr="http://schemas.android.com/apk/res-auto"
        android:id="@+id/ptrf_sv_patient_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/gray"
        android:dividerHeight="2dp"
        android:fadingEdge="horizontal"
        android:fastScrollEnabled="false"
        android:footerDividersEnabled="true"
        android:headerDividersEnabled="true"
        android:smoothScrollbar="true"
        android:background="@color/background_activity_dialog"
        ptr:ptrMode="pullUpFromBottom" />

</LinearLayout>

</LinearLayout>

被包裹的子布局
<?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:id="@+id/ll_ss_patient_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/shape"
android:gravity="center_horizontal"
android:focusable="true"
android:orientation="horizontal"
android:focusableInTouchMode="true"
android:layout_margin="@dimen/dimens_2_160">

<com.hospital.widget.EditTextSearch
android:id="@+id/et_ss_patient_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dimens_3_160"
android:layout_marginBottom="@dimen/dimens_3_160"
android:paddingLeft="@dimen/dimens_5_160"
android:paddingRight="@dimen/dimens_5_160"
android:drawableLeft="@drawable/ss"
android:drawablePadding="10dp"
android:hint="输入患者拼音首字母"
android:textColorHint="@color/color_tag_text_normal"
android:textColor="@color/color_tag_text_normal"
android:textSize="@dimen/dimens_8_160"
android:imeOptions="actionNext"
android:background="#00000000">

</com.hospital.widget.EditTextSearch>
</LinearLayout>

<com.hospital.widget.MyPullToRefreshGridView
android:id="@+id/gv_paitent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_activity_dialog"
android:horizontalSpacing="@dimen/dimens_4_160"
android:numColumns="1"
android:stretchMode="columnWidth"
android:verticalSpacing="@dimen/dimens_4_160" >
</com.hospital.widget.MyPullToRefreshGridView>

</LinearLayout>



三、代码
Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// 注册广播
registerBoradcastReceiver();

EventBus.getDefault().register(this);

View rootView = inflater.inflate(R.layout.patient_list, container, false);
View view = inflater.inflate(R.layout.patient_fragment_ptrfsv_item, null);

// 患者管理 搜索
ll_ss_patient_fragment = (LinearLayout) view.findViewById(R.id.ll_ss_patient_fragment);
et_ss_patient_fragment = (EditTextSearch) view.findViewById(R.id.et_ss_patient_fragment);

ll_ss_patient_fragment.setFocusable(true);
ll_ss_patient_fragment.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
et_ss_patient_fragment.setFocusable(true);
}
});

// 患者管理 条目
ptrf_sv_patient_fragment = (PullToRefreshScrollView) rootView.findViewById(R.id.ptrf_sv_patient_fragment);
ptrf_sv_patient_fragment.setMode(PullToRefreshBase.Mode.BOTH);

gv_paitent = (MyPullToRefreshGridView)view.findViewById(R.id.gv_paitent);
mPatientListAdapter = new PatientListAdapter(getActivity(), null);
gv_paitent.setAdapter(mPatientListAdapter);
ptrf_sv_patient_fragment.addView(view);

radioGroup = (RadioGroup) rootView.findViewById(R.id.rg_hzgl_patients);


// 关闭listitem_top_et软键盘
DesityUtil.closeKeyBoard(getActivity());

getPageNum();

// 获取患者分组标签名称
getPatientLable();

// 完整显示radioGroup
initRadioGroupAllView(sysLableList);

// 欠款患者分组统计
getPatientDetailsArrearsMoney();

// RadioGroup、EditText、ScrollView的监听事件
setListener();

// 根据CheckTag设置选中未选中状态、刷新gridView
refreshByCheckTag();

return rootView;
}

/**
* 监听
*/
private void setListener(){

// radioButton的点击监听
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
MonitorUserAction.addUserAction(MonitorUserAction.ACTIONPATIENTXXHZFZ);
// 分页恢复到默认
upOrDown = 1;
pageStart = 1;
// 搜索输入框失去焦点
et_ss_patient_fragment.clearFocus();
ll_ss_patient_fragment.requestFocus();
// Toast.makeText(getActivity(), "失去焦点", Toast.LENGTH_SHORT).show();
// 刷新患者列表
RadioButton tempButton2 = (RadioButton) getActivity().findViewById(checkedId);
if (tempButton2 != null) {
if (tempButton2.getTag().toString().equals("0")) { // 点击了全部患者选项
patientLabelId = "0";
getPatientDetails();
} else {
if (tempButton2.getTag().toString().equals("1")) { // 点击欠款患者选项
patientLabelId = "1";
getPatientDetailsArrears();
}else {
patientLabelId = tempButton2.getTag().toString(); // 点击标签分组患者
getPatientDetailsLable(patientLabelId);
}
}
}
// 遍历radiogroup里的button 设置字体颜色、背景
for (int i = 0; i < radioGroup.getChildCount(); i++) {
RadioButton tempButton1 = (RadioButton) group.getChildAt(i);
tempButton1.setTextColor(getResources().getColorStateList(R.color.prescription_gray_color));
tempButton1.setBackgroundResource(R.drawable.rb_bjys2);
if (radioGroup.getCheckedRadioButtonId() == tempButton1.getId()) {
rbCheckTag = tempButton1.getTag().toString();
tempButton1.setTextColor(getResources().getColor(R.color.white));
tempButton1.setBackgroundResource(R.drawable.rb_bjys);
}
}
// 关闭系统软键盘
DesityUtil.closeKeyBoard(getActivity());
}
});

// 搜索框的输入监听
et_ss_patient_fragment.addTextChangedListener(new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
// 分页恢复到默认
upOrDown = 1;
pageStart = 1;
String string = et_ss_patient_fragment.getText().toString();
if (string.length() != 0) {
getPatientListByShorthand(string);
}else {
getPatientDetails();
}
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub

}

@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub

}
});

// 搜索输入框焦点监听
et_ss_patient_fragment.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if (b){
// 分页恢复到默认
upOrDown = 1;
pageStart = 1;
// 恢复全部患者
rb_hzgl_all.setChecked(true);
rbCheckTag = rb_hzgl_all.getTag().toString();
getPatientDetails();
// LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, listitem_top_et.getHeight());
// et_ss_patient_fragment.setLayoutParams(lp1);
// Toast.makeText(getActivity(), "获取焦点", Toast.LENGTH_SHORT).show();
}else {
// LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
// et_ss_patient_fragment.setLayoutParams(lp2);
// Toast.makeText(getActivity(), "失去焦点", Toast.LENGTH_SHORT).show();
}
}
});

// ScrollView的下拉刷新监听
ptrf_sv_patient_fragment.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ScrollView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ScrollView> refreshView) {
// 下拉刷新
upOrDown = 1;
pageStart = 1;
refreshByCheckTag();
}

@Override
public void onPullUpToRefresh(PullToRefreshBase<ScrollView> refreshView) {
// 上拉加载
upOrDown = 0;
pageStart = pageStart + 1;
refreshByCheckTag();
}
});

}

具体可以再搭配查询本地数据库或者访问网络请求数据进行分页,
if (upOrDown == 1) {
mPatientListAdapter.updateDataClear(patientManageDTO);
}else {
mPatientListAdapter.updateDataNoClear(patientManageDTO);
}


adapter里关于数据源的设置updateDataClear与updateDataNoClear两个方法
package com.hospital.patient.adapter;

import java.text.ParseException;
import java.util.LinkedList;
import java.util.List;

import com.hospital.ConstantValue;
import com.hospital.R;
import com.hospital.log.error.MonitorUserAction;
import com.hospital.patient.PatientInfoEditActivity;
import com.hospital.patient.domain.PatientVO;
import com.hospital.patient.dto.PatientManageDTO;
import com.hospital.prescrible.PrescriptionActivity;
import com.hospital.utils.AgeUtils;
import com.hospital.utils.AnnotationClassUtil;
import com.hospital.utils.MoneyUtil;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
* 患者管理适配器
* @author wc
*/

public class PatientListAdapter extends BaseAdapter {

private Context context;
private List<PatientManageDTO> patients;
private LayoutInflater inflater;
ViewHolder viewHolder = null;

private int sex = 0;
private String sexLable = "";
public static String splitnei = "\\|\\|\\|";
public static String PATIENTLISTFRAGMENT = "patientListFragment";


public PatientListAdapter(Context context, List<PatientManageDTO> patients){
this.context = context;
if(patients == null){
this.patients = new LinkedList<>();
}else {
this.patients = patients;
}
inflater = LayoutInflater.from(context);
}

class ViewHolder {

}

@Override
public int getCount() {
// TODO Auto-generated method stub
return patients != null ? patients.size() : 0;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return patients.get(position);
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub

return convertView;
}

/**
* 刷新数据
*/
public void updateDataClear(List<PatientManageDTO> patients){
if (patients != null){
this.patients.clear();
this.patients.addAll(patients);
// Log.i("tag", "==========updateDataClear" + this.patients.size());
notifyDataSetChanged();
}
}

/**
* 刷新数据,清空之前数据
*/
public void updateDataNoClear(List<PatientManageDTO> patients){
if (patients != null){
this.patients.addAll(patients);
// Log.i("tag", "==========updateDataNoClear" + this.patients.size());
notifyDataSetChanged();
}
}

}

 

至此,PullToRefreshScrollView可以实时上下拉刷新GridView,并可以实现搜索框上下滑动显示、隐藏的功能

 









PullToRefreshScrollView实现顶层搜索框 滑动可隐藏 下面刷自定义GridView