两种方式实现类似qq搜索的切换

qq的搜索功能在点击搜索框时整个页面上移,出现透明布局。该效果是模仿iOS实现的,但是在Android也是很容易实现的。于是就花了点时间仿照效果写了一个demo。可能实现方式并不是完全相同。

具体请看效果图:


详细说明略。第一种是利用隐藏的透明LinearLayout实现效果。第二、三种是通过PopupWindow实现的,只有一处区别,即搜索框的两种状态。第二种采用的是ListView的addHeaderView实现的。

不多说直接上代码

第一种

/********************************************************** 
 * @文件名称:MainActivity.java 
 * @创建时间:2014年11月21日 下午8:12:24
 * @修改历史:2014年11月21日
 **********************************************************/
package com.jinlin.searchview;

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

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

/**
 * @author J!nl!n
 * @date 2014年11月21日
 * @time 下午8:12:24
 * @type MainActivity.java
 * @todo
 */
public class Activity1 extends Activity implements OnClickListener{
	protected static final String TAG = Activity1.class.getSimpleName();

	// 容器布局
	private LinearLayout container;

	// 标题栏布局
	private View titleView;

	private View searchView;

	private ListView listView;

	// 输入框是否获取到焦点
	private static boolean isFocused = false;

	// 图标居中输入框
	private EditText et_search;

	// 真是输入框
	private EditText et_input;

	// 取消按钮
	private Button btn_cancel;

	// 显示或隐藏软键盘
	private enum KeyBoardType {
		show, hide;
	}
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity1);
		initView();
	}

	private List<String> getData() {
		List<String> data = new ArrayList<String>();
		for (int i = 0; i < 100; i++) {
			data.add("测试数据" + i);
		}
		return data;
	}

	/**
	 * 【未做验证】这里需要注意在removeView之后,标题栏设置的监听事件是否失去,倘若在点击取消调用addView方法之后是否需要重新设置监听
	 */
	private void initView() {
		// 找到整个容器的布局
		container = ((LinearLayout) findViewById(R.id.container));
		// 获取标题栏布局
		titleView = findViewById(R.id.title_header);
		
		listView = (ListView) findViewById(R.id.listview);
		listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, getData()));
		
		// 找到隐藏的搜索布局
		searchView = findViewById(R.id.floatview);

		et_search = (EditText) findViewById(R.id.et_search);
		et_input = (EditText) findViewById(R.id.et_input);
		// 取消按钮
		btn_cancel = (Button) findViewById(R.id.btn_cancel);
		// 取消按钮设置监听
		btn_cancel.setOnClickListener(this);

		et_search.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					isFocused = true;
					// 显示隐藏的布局
					showSearchView(titleView);
					// 对软键盘及焦点的操作
					doSomething();
					break;
				}
				return false;
			}
		});
	}

	private void doSomething() {
		et_search.setFocusable(false);
		if (isFocused) {
			Toast.makeText(Activity1.this, "获取焦点", Toast.LENGTH_SHORT).show();
			et_input.setFocusable(true);
			et_input.setFocusableInTouchMode(true);
			et_input.requestFocus();
			// 显示软键盘
			operateKeyboard(KeyBoardType.show, container);
		}
	}
	
	/**
	 * 隐藏软键盘
	 * 
	 * @param v
	 */
	private void operateKeyboard(KeyBoardType type, View v) {
		InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
		if (type == KeyBoardType.show)
			imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);
		else
			imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
		setKeyboardDoneListener();
	}

	private void setKeyboardDoneListener() {
		// 软键盘回车完成监听
		et_input.setOnEditorActionListener(new OnEditorActionListener() {
			@Override
			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				if (actionId == EditorInfo.IME_ACTION_DONE) {
					operateKeyboard(KeyBoardType.hide, v);
					Log.d("1111", "done");

					// do something
					Toast.makeText(Activity1.this, et_input.getText().toString().trim(), Toast.LENGTH_SHORT).show();
					return true;
				}
				return false;
			}
		});
	}

	public void showSearchView(View view) {
		
		Animation translateAnimation = new TranslateAnimation(0, 0, 0, -getHeight(view));
		translateAnimation.setDuration(300);
		container.startAnimation(translateAnimation);
		translateAnimation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation arg0) {
			}

			@Override
			public void onAnimationRepeat(Animation arg0) {
			}

			@Override
			public void onAnimationEnd(Animation arg0) {
				TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 0);
				container.setAnimation(anim);
				
				titleView.setVisibility(View.GONE);
				titleView.setPadding(0, -getHeight(titleView), 0, 0);
				// 显示隐藏的布局
				searchView.setVisibility(View.VISIBLE);
			}
		});
	}
	
	/**
	 * 
	 */
	private int getHeight(View view) {
		return view.getHeight();
	}

	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		super.onWindowFocusChanged(hasFocus);
		Toast.makeText(this, "高度是:" + getHeight(titleView), Toast.LENGTH_SHORT).show();
	}
	
	private void resetUI(View view) {
		operateKeyboard(KeyBoardType.hide, view);
		// 继续隐藏搜索布局
		searchView.setVisibility(View.GONE);
		
		titleView.setPadding(0, 0, 0, 0);
		titleView.setVisibility(View.VISIBLE);
		
		Animation translateAnimation = new TranslateAnimation(0, 0, -getHeight(titleView), 0);
		translateAnimation.setDuration(300);
		container.startAnimation(translateAnimation);
		translateAnimation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation arg0) {
				
			}

			@Override
			public void onAnimationRepeat(Animation arg0) {

			}

			@Override
			public void onAnimationEnd(Animation arg0) {
				TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 0);
				container.setAnimation(anim);
			}
		});
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_cancel:
			isFocused = false;
			resetUI(v);
			break;

		default:
			break;
		}
	}

}

第二种

/********************************************************** 
 * @文件名称:Activity2.java 
 * @创建时间:2014年11月22日 下午9:54:31
 * @修改历史:2014年11月22日
 **********************************************************/
package com.jinlin.searchview;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

/**
 * @author J!nl!n
 * @date 2014年11月22日
 * @time 下午9:54:31
 * @type Activity2.java
 * @todo
 */
public class Activity2 extends Activity implements OnClickListener, OnItemClickListener,
		PopupWindow.OnDismissListener {
	private TextView tv_top_title;
	
	private ListView listView;
	private View headerView;
	private TextView tv_search;

	// show and hide
	private RelativeLayout mainLayout;
	private RelativeLayout titleBarLayout;
	private int moveHeight;
	private int statusBarHeight;

	// search popupwindow
	private PopupWindow popupWindow;
	private View searchView;
	private EditText searchEditText;
	private TextView cancelTextView;
	private ListView filterListView;
	private View alphaView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity2);

		tv_top_title = (TextView) findViewById(R.id.tv_top_title);
		tv_top_title.setText("我是第二种");
		initCtrl();
	}

	@Override
	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.tv_search:
			showSearchBar();
			break;
		case R.id.popup_window_tv_cancel:
			dismissPopupWindow();
			break;
		case R.id.popup_window_v_alpha:
			dismissPopupWindow();
			break;
		}
	}

	@Override
	public void onItemClick(AdapterView<?> viewGroup, View view, int position, long arg3) {
		switch (viewGroup.getId()) {
		case R.id.lv:
			if (position == 0) {
				showSearchBar();
			}
			break;
		case R.id.popup_window_lv:
			Toast.makeText(Activity2.this, "click-" + position, Toast.LENGTH_LONG).show();
			break;
		}
	}

	@Override
	public void onDismiss() {
		resetUI();
	}

	private void initCtrl() {
		listView = (ListView) findViewById(R.id.lv);
		LayoutInflater mInflater = LayoutInflater.from(this);
		headerView = mInflater.inflate(R.layout.activity2_3_search, null);
		listView.addHeaderView(headerView);
		listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getData()));
		listView.setOnItemClickListener(this);
		tv_search = (TextView) headerView.findViewById(R.id.tv_search);
		tv_search.setOnClickListener(this);

		mainLayout = (RelativeLayout) findViewById(R.id.main);
		titleBarLayout = (RelativeLayout) findViewById(R.id.title_bar_layout);

		searchView = mInflater.inflate(R.layout.popup_window_search, null);
		searchEditText = (EditText) searchView.findViewById(R.id.popup_window_et_search);
		searchEditText.setFocusable(true);
		searchEditText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				if (s.toString().equals("")) {
					alphaView.setVisibility(View.VISIBLE);
					filterListView.setVisibility(View.GONE);
				} else {
					alphaView.setVisibility(View.GONE);
					filterListView.setVisibility(View.VISIBLE);
				}
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {
			}
		});

		cancelTextView = (TextView) searchView.findViewById(R.id.popup_window_tv_cancel);
		cancelTextView.setOnClickListener(this);
		filterListView = (ListView) searchView.findViewById(R.id.popup_window_lv);
		filterListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getData2()));
		filterListView.setOnItemClickListener(this);
		alphaView = searchView.findViewById(R.id.popup_window_v_alpha);
		alphaView.setOnClickListener(this);

		popupWindow = new PopupWindow(searchView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		popupWindow.setFocusable(true);
		popupWindow.setOutsideTouchable(true);
		popupWindow.setTouchable(true);
		popupWindow.setBackgroundDrawable(new BitmapDrawable());
		popupWindow.setOnDismissListener(this);
	}

	private List<String> getData() {
		List<String> data = new ArrayList<String>();
		for (int i = 0; i < 100; i++) {
			data.add("测试数据" + i);
		}
		return data;
	}

	private List<String> getData2() {
		List<String> data = new ArrayList<String>();
		for (int i = 0; i < 100; i++) {
			data.add("搜索数据" + i);
		}
		return data;
	}

	private void getStatusBarHeight() {
		Rect frame = new Rect();
		getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
		statusBarHeight = frame.top;
	}

	private void showSearchBar() {
		getStatusBarHeight();
		moveHeight = titleBarLayout.getHeight();
		Animation translateAnimation = new TranslateAnimation(0, 0, 0, -moveHeight);
		translateAnimation.setDuration(300);
		mainLayout.startAnimation(translateAnimation);
		translateAnimation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation arg0) {
			}

			@Override
			public void onAnimationRepeat(Animation arg0) {

			}

			@Override
			public void onAnimationEnd(Animation arg0) {
				TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 0);
				mainLayout.setAnimation(anim);
				titleBarLayout.setVisibility(View.GONE);
				titleBarLayout.setPadding(0, -moveHeight, 0, 0);

				popupWindow.showAtLocation(mainLayout, Gravity.CLIP_VERTICAL, 0, statusBarHeight);
				openKeyboard();
			}
		});

	}

	private void openKeyboard() {
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
				imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
			}
		}, 0);
	}

	private void dismissPopupWindow() {
		if (popupWindow != null && popupWindow.isShowing()) {
			popupWindow.dismiss();
		}
	}

	private void resetUI() {
		titleBarLayout.setPadding(0, 0, 0, 0);
		titleBarLayout.setVisibility(View.VISIBLE);
		Animation translateAnimation = new TranslateAnimation(0, 0, -moveHeight, 0);
		translateAnimation.setDuration(300);
		mainLayout.startAnimation(translateAnimation);
		translateAnimation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation arg0) {

			}

			@Override
			public void onAnimationRepeat(Animation arg0) {

			}

			@Override
			public void onAnimationEnd(Animation arg0) {
				TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 0);
				mainLayout.setAnimation(anim);
				// titleBarLayout.setPadding(0, 0, 0, 0);

			}
		});
	}

}

第三种

/********************************************************** 
 * @文件名称:Activity3.java 
 * @创建时间:2014年11月22日 下午9:54:53
 * @修改历史:2014年11月22日
 **********************************************************/
package com.jinlin.searchview;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

/**
 * @author J!nl!n
 * @date 2014年11月22日
 * @time 下午9:54:53
 * @type Activity3.java
 * @todo
 */
public class Activity3 extends Activity implements OnClickListener, OnItemClickListener, PopupWindow.OnDismissListener {
	private TextView tv_top_title;
	
	private ListView listView;
	private TextView tv_search;

	// show and hide
	private LinearLayout mainLayout;
	private RelativeLayout titleBarLayout;
	private int moveHeight;
	private int statusBarHeight;

	// search popupwindow
	private PopupWindow popupWindow;
	private View searchView;
	private EditText searchEditText;
	private TextView cancelTextView;
	private ListView filterListView;
	private View alphaView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity3);

		tv_top_title = (TextView) findViewById(R.id.tv_top_title);
		tv_top_title.setText("我是第三种");
		initCtrl();
	}

	@Override
	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.tv_search:
			showSearchBar();
			break;
		case R.id.popup_window_tv_cancel:
			dismissPopupWindow();
			break;
		case R.id.popup_window_v_alpha:
			dismissPopupWindow();
			break;
		}
	}

	@Override
	public void onItemClick(AdapterView<?> viewGroup, View view, int position, long arg3) {
		switch (viewGroup.getId()) {
		case R.id.lv:
			if (position == 0) {
				showSearchBar();
			}
			break;
		case R.id.popup_window_lv:
			Toast.makeText(Activity3.this, "click-" + position, Toast.LENGTH_LONG).show();
			break;
		}
	}

	@Override
	public void onDismiss() {
		resetUI();
	}

	private void initCtrl() {
		listView = (ListView) findViewById(R.id.lv);

		LayoutInflater mInflater = LayoutInflater.from(this);

		listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getData()));
		listView.setOnItemClickListener(this);

		tv_search = (TextView) findViewById(R.id.tv_search);
		tv_search.setOnClickListener(this);

		mainLayout = (LinearLayout) findViewById(R.id.mainLayout);
		titleBarLayout = (RelativeLayout) findViewById(R.id.title_bar_layout);

		searchView = mInflater.inflate(R.layout.popup_window_search, null);
		searchEditText = (EditText) searchView.findViewById(R.id.popup_window_et_search);
		searchEditText.setFocusable(true);
		searchEditText.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				if (s.toString().equals("")) {
					alphaView.setVisibility(View.VISIBLE);
					filterListView.setVisibility(View.GONE);
				} else {
					alphaView.setVisibility(View.GONE);
					filterListView.setVisibility(View.VISIBLE);
				}
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {
			}
		});

		cancelTextView = (TextView) searchView.findViewById(R.id.popup_window_tv_cancel);
		cancelTextView.setOnClickListener(this);
		filterListView = (ListView) searchView.findViewById(R.id.popup_window_lv);
		filterListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, getData2()));
		filterListView.setOnItemClickListener(this);
		alphaView = searchView.findViewById(R.id.popup_window_v_alpha);
		alphaView.setOnClickListener(this);

		popupWindow = new PopupWindow(searchView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		popupWindow.setFocusable(true);
		popupWindow.setOutsideTouchable(true);
		popupWindow.setTouchable(true);
		popupWindow.setBackgroundDrawable(new BitmapDrawable());
		popupWindow.setOnDismissListener(this);
	}

	private List<String> getData() {
		List<String> data = new ArrayList<String>();
		for (int i = 0; i < 100; i++) {
			data.add("测试数据" + i);
		}
		return data;
	}

	private List<String> getData2() {
		List<String> data = new ArrayList<String>();
		for (int i = 0; i < 100; i++) {
			data.add("搜索数据" + i);
		}
		return data;
	}

	private void getStatusBarHeight() {
		Rect frame = new Rect();
		getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
		statusBarHeight = frame.top;
	}

	private void showSearchBar() {
		getStatusBarHeight();
		moveHeight = titleBarLayout.getHeight();
		Animation translateAnimation = new TranslateAnimation(0, 0, 0, -moveHeight);
		translateAnimation.setDuration(300);
		mainLayout.startAnimation(translateAnimation);
		translateAnimation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation arg0) {
			}

			@Override
			public void onAnimationRepeat(Animation arg0) {

			}

			@Override
			public void onAnimationEnd(Animation arg0) {
				TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 0);
				mainLayout.setAnimation(anim);
				titleBarLayout.setVisibility(View.GONE);
				titleBarLayout.setPadding(0, -moveHeight, 0, 0);

				popupWindow.showAtLocation(mainLayout, Gravity.CLIP_VERTICAL, 0, statusBarHeight);
				openKeyboard();
			}
		});

	}

	private void openKeyboard() {
		Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
				imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
			}
		}, 0);
	}

	private void dismissPopupWindow() {
		if (popupWindow != null && popupWindow.isShowing()) {
			popupWindow.dismiss();
		}
	}

	private void resetUI() {
		titleBarLayout.setPadding(0, 0, 0, 0);
		titleBarLayout.setVisibility(View.VISIBLE);
		Animation translateAnimation = new TranslateAnimation(0, 0, -moveHeight, 0);
		translateAnimation.setDuration(300);
		mainLayout.startAnimation(translateAnimation);
		translateAnimation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation arg0) {

			}

			@Override
			public void onAnimationRepeat(Animation arg0) {

			}

			@Override
			public void onAnimationEnd(Animation arg0) {
				TranslateAnimation anim = new TranslateAnimation(0, 0, 0, 0);
				mainLayout.setAnimation(anim);
				// titleBarLayout.setPadding(0, 0, 0, 0);

			}
		});
	}

}
githib地址:https://github.com/5peak2me/QQSearchView
源码飞机票

你可能感兴趣的:(两种方式实现类似qq搜索的切换)