1.MyOpenHelper (数据库)
public class MyOpenHelper extends SQLiteOpenHelper{
public MyOpenHelper(Context context) {
super(context, "demo.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建数据库的时候,创建表格
db.execSQL("create table history(_id INTEGER primary key autoincrement,content varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
2.MySearchView (搜索框)
public class MySearchView extends LinearLayout{
private EditText et_search;
public MySearchView(Context context) {
this(context,null);
}
public MySearchView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public MySearchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
View view = View.inflate(context, R.layout.searchview_layout, this);
et_search = (EditText)view.findViewById(R.id.et_search);
}
//获取信息
public String getContent(){
return et_search.getText().toString();
}
}
2.5 searchview_layout(搜索框对应的布局)
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/seach_bg"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="6px">
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/a_4"/>
android:layout_width="0dp"
android:layout_height="match_parent"
android:id="@+id/et_search"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:background="@null"
android:hint="请输入要搜索的关键词"
android:textColor="#333"
android:textColorHint="#666"
android:textSize="12sp" />
3.MyFlowLayout (流式布局)
public class MyFlowLayout extends ViewGroup{
private int useWidth;
private int MaxHeight;
private int HorizonytalSpace = 5;
private int VerticalSpaace = 5;
private Line mLine;
private int MaxLine = 100;
private ArrayList LineList = new ArrayList();
// private int
public MyFlowLayout(Context context) {
super(context);
}
public MyFlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//获取控件的具体尺寸
int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();//获取空间的宽度
int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();//获取控件的高度
//获取控件的测量模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);//宽度的测量模式
int heightMode = MeasureSpec.getMode(heightMeasureSpec);//高度的测量模式
//开始遍历所有的子控件
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
//获取子控件的尺寸,与测量模式
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width,widthMode == MeasureSpec.EXACTLY?MeasureSpec.AT_MOST:widthMode);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height,heightMode == MeasureSpec.EXACTLY?MeasureSpec.AT_MOST:heightMode);
//测量子控件
childView.measure(childWidthMeasureSpec,childHeightMeasureSpec);
int childWidth = childView.getMeasuredWidth();//子控件的宽度
int childHeight = childView.getMeasuredHeight();//子控件的高度
useWidth += childWidth;
if(mLine == null){
mLine = new Line();
}
if(useWidth < width){
//未超过最大限度,可以添加到当前行
mLine.addView(childView);
useWidth += HorizonytalSpace;
if(useWidth >= width){
if(!newLine()){
break;//创建失败,结束for循环
}
}
}else {
//2.但前行没有控件,必须加入到当前行,然后换行
if(mLine.getLineCount() == 0){
//添加到当前行,然后换行
mLine.addView(childView);
LineList.add(mLine);
if(!newLine()){
break;
}
}else {
//超过最大高度,
//1.当前行有控件,需要新建一行
if(!newLine()){
break;
}
mLine.addView(childView);
useWidth += HorizonytalSpace + childWidth;
}
}
if (mLine != null && mLine.getLineCount() > 0
&& !LineList.contains(mLine)) {
// 由于前面采用判断长度是否超过最大宽度来决定是否换行,则最后一行可能因为还没达到最大宽度,所以需要验证后加入集合中
LineList.add(mLine);
}
}
//为控件设置宽度,高度
int Totalwidth = MeasureSpec.getSize(widthMeasureSpec);
int TotalHeight = 0;
for (int i = 0; i TotalHeight += LineList.get(i).MaxHeight;
}
TotalHeight += (LineList.size() - 1)*VerticalSpaace + getPaddingTop() + getPaddingBottom();
setMeasuredDimension(Totalwidth,TotalHeight);
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//遍历行集合(LineList),
int Top = getPaddingTop();
int Left = getPaddingLeft();
for (int i = 0; i < LineList.size(); i++) {
Line line = LineList.get(i);
line.layoutView(Left,Top);
Top += line.MaxHeight + VerticalSpaace;
}
}
private boolean newLine(){
//判断是否超过最大行数
if(LineList.size() < MaxLine){
//将上一行添加到,LineList中
LineList.add(mLine);
mLine = new Line();//创建一个新的行
//新的一行,使用的数据为0
useWidth = 0;
MaxHeight = 0;
return true;//创建成功返回true
}
return false;
}
//创建一个类,用来处理每一行的数据
class Line{
private int mLineWidth = 0;
private int MaxHeight = 0;
private ArrayList viewlist = new ArrayList();
public void addView(View view){
viewlist.add(view);
mLineWidth += view.getMeasuredWidth();
int childHeight = view.getMeasuredHeight();
MaxHeight = MaxHeight < childHeight?childHeight:MaxHeight;
}
public int getLineCount(){
return viewlist.size();
}
public void layoutView(int l,int t){
//对此行的数据进行布局
int Left = l;
int Top = t;
int childCount = viewlist.size();
int width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() -(childCount-1) * HorizonytalSpace;
//计算剩余宽度
int surplusWidth = width - mLineWidth;
if(surplusWidth > 0){
//计算每个布局的添加量
int widthOffSet = (int) (surplusWidth * 1.0f/viewlist.size() + 0.5f);
for (int i = 0; i < viewlist.size(); i++) {
View view = viewlist.get(i);
int childWidth = view.getMeasuredWidth();
int childHeight = view.getMeasuredHeight();
childWidth += widthOffSet;//重新分配控件的高度
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth,MeasureSpec.EXACTLY);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight,MeasureSpec.EXACTLY);
view.measure(childWidthMeasureSpec,childHeightMeasureSpec);
//分配布局控件时的偏移量
int TopOffSet = (MaxHeight - childHeight) / 2;
TopOffSet = TopOffSet>0?TopOffSet:0;//如果TopOffSet(竖直方向的偏移量)小于0,则设置为0;
view.layout(Left,Top+ TopOffSet,Left +childWidth,Top + TopOffSet + childHeight);
Left += HorizonytalSpace + childWidth;
}
}else{
}
}
}
public void setHorizontalSpacing(int horizonytalSpace) {
HorizonytalSpace = horizonytalSpace;
}
public void setVerticalSpacing(int verticalSpaace) {
VerticalSpaace = verticalSpaace;
}
}
4.MainActivity (主方法)
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private MyOpenHelper myOpenHelper;
private MySearchView mySearchView;
private MyFlowLayout myFlowLayout;
private MyListView myListView;
private TextView sousuo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化页面
initViews();
//初始化数据库
initDatabase();
}
private void initDatabase() {
myOpenHelper = new MyOpenHelper(this);
SQLiteDatabase database = myOpenHelper.getReadableDatabase();
}
private void initViews() {
mySearchView = (MySearchView)findViewById(R.id.mySearchView);
myFlowLayout = (MyFlowLayout)findViewById(R.id.flow_hot_search);
myListView = (MyListView)findViewById(R.id.lv_search);
sousuo = (TextView)findViewById(R.id.sousuo);
sousuo.setOnClickListener(this);
ImageView dele = (ImageView) findViewById(R.id.iv_delete);
dele.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sousuo:
//获取数据
String con = mySearchView.getContent();
//存入数据库
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("content", con);
db.insert("history", null, contentValues);
db.close();
//展示在列表
// 查询数据
SQLiteDatabase db1 = myOpenHelper.getReadableDatabase();
Cursor cursor = db1.query("history", null, null, null, null, null, null);
List list = new ArrayList<>();
while (cursor.moveToNext()) {
String content = cursor.getString(cursor.getColumnIndex("content"));
list.add(content);
}
db1.close();
//设置适配器
MyAdapter myAdapter = new MyAdapter(MainActivity.this, list);
myListView.setAdapter(myAdapter);
break;
case R.id.iv_delete:
SQLiteDatabase db2 = myOpenHelper.getReadableDatabase();
db2.delete("history",null,null);
db2.close();
SQLiteDatabase db3 = myOpenHelper.getReadableDatabase();
Cursor cursor3 = db3.query("history", null, null, null, null, null, null);
List list1 = new ArrayList<>();
while (cursor3.moveToNext()) {
String content = cursor3.getString(cursor3.getColumnIndex("content"));
list1.add(content);
}
db3.close();
//设置适配器
MyAdapter myAdapter2 = new MyAdapter(MainActivity.this, list1);
myListView.setAdapter(myAdapter2);
break;
}
}
}
4.5 activity_main(主布局)
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context="com.example.myzhoukao1_shizuo.MainActivity">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:id="@+id/mySearchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
android:id="@+id/sousuo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="搜索"
android:textSize="20sp" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20px"
android:text="热门搜索"
android:textSize="36px" />
android:id="@+id/flow_hot_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#F00"
android:text="电饭煲" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#F00"
android:text="手机" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20px">
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="历史搜索"
android:textSize="36px" />
android:id="@+id/iv_delete"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/cha" />
android:id="@+id/lv_search"
android:layout_width="match_parent"
android:layout_height="match_parent">
5.MyAdapter (适配器)
public class MyAdapter extends BaseAdapter{
private final Context context;
private final List list;
public MyAdapter(Context context, List list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(context);
textView.setText(list.get(position));
textView.setTextSize(20);
return textView;
}
}
6.MyListView (防止历史记录只显示一行)
public class MyListView extends ListView{
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMea = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMea);
}
}
7.seach_bg(搜索框背景布局一般写在drawable里)
android:shape="rectangle">
android:width="100dp"
android:height="30dp" />
8.效果图