现在的位置: 首页 > 综合 > 正文

Anroid自定义控件/继承自ViewGroup的刷新控件——LinearLayout

2018年05月26日 ⁄ 综合 ⁄ 共 10267字 ⁄ 字号 评论关闭

选择ViewGroup而不是单个View的理由就是通用性

下拉过程分为3个状态

1.下拉,未满足释放刷新的高度,显示“下拉刷新”

2.下拉,满足释放刷新的高度,显示“释放刷新”

3.释放,显示“刷新”

接着我们Touch事件 有

1. 按下

2.按下移动

3.松开

<<刷新控件Demo下载地址>>

接着必须要知道的方法onInterceptTouchEvent,用于在OnTouchEvent之前截取一次事件

public boolean onInterceptTouchEvent(MotionEvent event)
return false;//表示未消费此事件,将事件传递下一层View
return true;//表示消费了此事件,将不再下传

用于主要的逻辑处理

public boolean onTouchEvent(MotionEvent event)

通过判断HeaderView的TopMargin来判断是否满足释放刷新条件

Code:

public class RefreshView extends LinearLayout{

	private Scroller scroller;
	private LinearLayout refreshView;
	private ImageView refreshIndicatorView;
	private int refreshTargetTop = -60;
	private ProgressBar bar;
	private TextView downTextView;
	private TextView timeTextView;
	private LinearLayout refereshLinearLayout;
	private RefreshListener refreshListener;
	private String downTextString;
	private String releaseTextString;
	private Long refreshTime = null;
	private int lastX;
	private int lastY;
	private boolean isDragging = false;// 拉动标记
	private boolean isRefreshEnabled = true;// 是否可刷新标记
	private boolean isRefreshing = false;// 在刷新中标记
	private Context mContext;
	
	public RefreshView(Context context) {
		// TODO Auto-generated constructor stub
		this(context, null);
	}

	public RefreshView(Context context,AttributeSet attrs) {
		super(context,attrs);
		// TODO Auto-generated constructor stub
		mContext = context;
		init();
	}
	
	private void init(){
		scroller = new Scroller(mContext);
		refreshView =(LinearLayout)View.inflate(mContext, R.layout.refresh_top_item, null);
		// 拉动时候的视图
		refreshIndicatorView = (ImageView)refreshView.findViewById(R.id.indicator);
		downTextView = (TextView)refreshView.findViewById(R.id.refresh_hint);
		// 刷新时候的视图
		refereshLinearLayout = (LinearLayout)refreshView
					.findViewById(R.id.referesh_linearlayout);
		bar = (ProgressBar)refreshView.findViewById(R.id.progress);
		timeTextView =(TextView)refreshView.findViewById(R.id.refresh_time);
		
		LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT
					, -refreshTargetTop);
		lp.topMargin = refreshTargetTop;
		lp.gravity = Gravity.CENTER;
		addView(refreshView,lp);
		downTextString = mContext.getResources()
					.getString(R.string.refresh_down_text);
		releaseTextString = mContext.getResources()
					.getString(R.string.refresh_release_text);
	}


	
	// 首次截取   事件
	@Override
	public boolean onInterceptTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		
		int y = (int) event.getY();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			lastY = y;
			break;
		case MotionEvent.ACTION_MOVE:
			int m = y - lastY;
			lastY = y;
			if(canScroll(m)){
				return true;
			}
			break;
		}
		return false;
	}
	
	
	
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		
		
		if(isRefreshing)	return false;
		int y = (int) event.getY();
		switch(event.getAction()){
		
		case MotionEvent.ACTION_DOWN:
			lastY = y;
			break;
		case MotionEvent.ACTION_MOVE:
			int m = y - lastY;
			doMovement(m);
			lastY = y;
			break;
		case MotionEvent.ACTION_UP:
			fling();
			break;
		}
		
		
		
		
		return true;
	}

	private void fling(){
		if(isRefreshing)	return;
		LinearLayout.LayoutParams lp = (LayoutParams)refreshView
			.getLayoutParams();
		if(lp.topMargin > 0){
			refresh();
		}else{
			returnInitState();
		}
	}
	
	private void returnInitState() {
		// TODO Auto-generated method stub
		LinearLayout.LayoutParams lp = (LayoutParams)refreshView
				.getLayoutParams();
		int i = lp.topMargin;
		scroller.startScroll(0, i, 0, refreshTargetTop - i);// 回滚到初始状态
		invalidate();
	}

	private void refresh() {
		// TODO Auto-generated method stub
		LinearLayout.LayoutParams lp = (LayoutParams)refreshView
			.getLayoutParams();
		int i = lp.topMargin;
		refreshIndicatorView.setVisibility(View.GONE);
		downTextView.setVisibility(View.GONE);
		refereshLinearLayout.setVisibility(View.VISIBLE);
		
		// 回滚到第一格位置
		scroller.startScroll(0, i, 0, -i);
		invalidate();
		
		if(refreshListener != null){
			refreshListener.onRefresh(this);
			isRefreshing = true;
		}
		
	}
	
	public void finishRefresh() {
		LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView
				.getLayoutParams();
		int i = lp.topMargin;
		
		scroller.startScroll(0, i, 0, refreshTargetTop);
		invalidate();
		// refreshIndicatorView.setVisibility(View.VISIBLE);
		// timeTextView.setVisibility(View.VISIBLE);
		isRefreshing = false;
		setRefreshDate(Calendar.getInstance().getTime());
	}
	
	@Override
	public void computeScroll() {
		// TODO Auto-generated method stub
		//super.computeScroll();
		if(scroller.computeScrollOffset()){
			int i = this.scroller.getCurrY();
			LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.refreshView
					.getLayoutParams();
			lp.topMargin = i;
			refreshView.setLayoutParams(lp);
			refreshView.invalidate();
			invalidate();
		}
	}
	
	

	private void doMovement(int moveY){
		
		LinearLayout.LayoutParams lp = (LayoutParams)refreshView.getLayoutParams();
		
		lp.topMargin = (int)(lp.topMargin + moveY * 0.3);// 修改上边距
		refreshView.setLayoutParams(lp);
		refreshView.invalidate();
		invalidate();		
		
		if(refreshTime != null)	setRefreshTime(refreshTime);
		
		downTextView.setVisibility(View.VISIBLE);
		refreshIndicatorView.setVisibility(View.VISIBLE);
		
		if(lp.topMargin > 0){
			downTextView.setText(mContext.getResources().getString(R.string.refresh_release_text));
			refreshIndicatorView.setImageResource(R.drawable.refresh_arrow_up);
		}else{
			downTextView.setText(mContext.getResources().getString(R.string.refresh_down_text));
			refreshIndicatorView.setImageResource(R.drawable.refresh_arrow_down);
		}
	}
	
	private void setRefreshTime(Long time){
		refreshTime = time;
	}
	
	public void setRefreshEnabled(boolean b) {
		this.isRefreshEnabled = b;
	}
	
	public void setRefreshListener(RefreshListener listener) {
		this.refreshListener = listener;
	}
	
	private void setRefreshDate(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("MM-dd hh:mm");
		timeTextView.setText("更新与:" + format.format(date));
	}
	
	private boolean canScroll(int moveY){
		View childView;
		if(moveY < 0){
			return false;
		}
		if(getChildCount() > 1){
			childView = this.getChildAt(1);
			if(childView instanceof ListView){
				if(((ListView) childView).getFirstVisiblePosition() == 0)
					return true;
				else	
					return false;
			}else if (childView instanceof ScrollView){
				if(((ScrollView)childView).getScrollY() == 0)
					return true;
				else
					return false;
			}else if(childView instanceof GridView){
				if(((GridView) childView).getFirstVisiblePosition() == 0)
					return true;
				else
					return false;
			}
		}
		return true;
	}
	
	public interface RefreshListener {
		public void onRefresh(RefreshView view);
	}
	
}

refresh_top_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:background="#EEEEEEEE"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/indicator"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/refresh_hint"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/referesh_linearlayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ProgressBar
            android:id="@+id/progress"
            style="?android:attr/progressBarStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="正在获取数据..." />

            <TextView
                android:id="@+id/refresh_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="更新与:" />
        </LinearLayout>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>

</LinearLayout>

Adapter

import java.util.List;

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyListAdapter extends BaseAdapter	{
	List<String> list;
	
	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return list.size();
	}

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

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		
		TextView textview = new TextView(parent.getContext());
		textview.setText(list.get(list.size()-position-1));
		
		return textview;
	}

	public List<String> getList() {
		return list;
	}

	public void setList(List<String> list) {
		this.list = list;
	}
}

Activity

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ListView;

import com.ishow.chenjq.RefreshView;
import com.ishow.chenjq.RefreshView.RefreshListener;;

public class MainActivity extends Activity {
	private RefreshView refreshableLinearLayout;
	private ListView listView;
	private MyListAdapter adapter;
	private List<String> list;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		preinitUI();
		initUI();
	}

	private void preinitUI() {
		adapter = new MyListAdapter();
		list = new ArrayList<String>();
		addLists(10);
		adapter.setList(list);
	}

	private void initUI() {
		setContentView(R.layout.referesh_view);
		refreshableLinearLayout = (RefreshView) findViewById(R.id.refresh_root);
		refreshableLinearLayout.setRefreshListener(listener);
		
		listView = (ListView) findViewById(R.id.listview);
		listView.setAdapter(adapter);
	}
	
	RefreshListener listener = new RefreshListener() {
		@Override
		public void onRefresh(RefreshView view) {
			referesh();
		}
	};


	protected void referesh() {
		new AsyncTask<Void, Void, Void>() {
			protected Void doInBackground(Void... params) {
				try {
					Thread.sleep(2000);
				} catch (Exception e) {
					e.printStackTrace();
				}
				return null;
			}

			@Override
			protected void onPostExecute(Void result) {
				addLists(1);
				refreshableLinearLayout.finishRefresh();
			}

		}.execute();
	}
	
	
    private void addLists(int n){
		
   	 n += list.size();
   	 for(int i=list.size();i<n;i++){
	        list.add("选项"+i);
	     }
   }
}

Activity布局

<?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.ishow.chenjq.RefreshView
        android:id="@+id/refresh_root"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <ListView
            android:id="@+id/listview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:paddingTop="100px"
            android:paddingBottom="80px"
            android:paddingRight="90px"
            android:paddingLeft="10px"
            android:cacheColorHint="@android:color/transparent"
            android:descendantFocusability="blocksDescendants"
            android:divider="#FFCC00"
            android:dividerHeight="0dip" />
    </com.ishow.chenjq.RefreshView>

</LinearLayout>

抱歉!评论已关闭.