1.先配置GreenDao,Butterknife和EventBus
1.在model的build中加入依赖
//greendao
compile 'org.greenrobot:greendao:3.1.0'
compile 'org.greenrobot:greendao-generator:3.0.0'
//butterknife 黄油刀
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
//EventBus
compile 'org.greenrobot:eventbus:3.0.0'
**2.到这里EventBus已经配置完成,接着就是GreenDao和Butterknife了:
在model的build中添加:**
apply plugin: 'com.jakewharton.butterknife'//butterknife
apply plugin: 'org.greenrobot.greendao'//greendao
3.在model的最下面添加:
// 配置GreenDao基本参数
greendao {
//设置当前数据库版本
schemaVersion 1
//dao的包名,默认的是entity所在的包
daoPackage '包名+dao'
//生成数据库文件的目录
targetGenDir 'src/main/java'
}
4.在工程的build中的dependencies里添加greendao和butterknife的配置:
//butterknife
classpath 'com.jakewharton:butterknife-gradle-plugin:8.5.1'
//greendao
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
到这里,这三个功能已经配置完成了,可以使用了。
2.首先是流失布局的配置,自定义继承ViewGroup设置
**1.自定义流式布局**
public class ReSouView extends ViewGroup {
//存储所有子View
private List<List<View>> mAllChildViews = new ArrayList<>();
//每一行的高度
private List<Integer> mLineHeight = new ArrayList<>();
public ReSouView(Context context) {
super(context);
}
public ReSouView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ReSouView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mAllChildViews.clear();
mLineHeight.clear();
//获取当前ViewGroup的宽度
int width = getWidth();
int lineWidth = 0;
int lineHeight = 0;
//记录当前行的view
List<View> lineViews = new ArrayList<View>();
int childCount = getChildCount();
for(int i = 0;i < childCount; i ++){
View child = getChildAt(i);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth();
int childHeight = child.getMeasuredHeight();
//如果需要换行
if(childWidth + lineWidth + lp.leftMargin + lp.rightMargin > width){
//记录LineHeight
mLineHeight.add(lineHeight);
//记录当前行的Views
mAllChildViews.add(lineViews);
//重置行的宽高
lineWidth = 0;
lineHeight = childHeight + lp.topMargin + lp.bottomMargin;
//重置view的集合
lineViews = new ArrayList();
}
lineWidth += childWidth + lp.leftMargin + lp.rightMargin;
lineHeight = Math.max(lineHeight, childHeight + lp.topMargin + lp.bottomMargin);
lineViews.add(child);
}
//处理最后一行
mLineHeight.add(lineHeight);
mAllChildViews.add(lineViews);
//设置子View的位置
int left = 0;
int top = 0;
//获取行数
int lineCount = mAllChildViews.size();
for(int i = 0; i < lineCount; i ++){
//当前行的views和高度
lineViews = mAllChildViews.get(i);
lineHeight = mLineHeight.get(i);
for(int j = 0; j < lineViews.size(); j ++){
View child = lineViews.get(j);
//判断是否显示
if(child.getVisibility() == View.GONE){
continue;
}
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int cLeft = left + lp.leftMargin;
int cTop = top + lp.topMargin;
int cRight = cLeft + child.getMeasuredWidth();
int cBottom = cTop + child.getMeasuredHeight();
//进行子View进行布局
child.layout(cLeft, cTop, cRight, cBottom);
left += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
}
left = 0;
top += lineHeight;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//父控件传进来的宽度和高度以及对应的测量模式
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
//如果当前ViewGroup的宽高为wrap_content的情况
int width = 0;//自己测量的 宽度
int height = 0;//自己测量的高度
//记录每一行的宽度和高度
int lineWidth = 0;
int lineHeight = 0;
//获取子view的个数
int childCount = getChildCount();
for(int i = 0;i < childCount; i ++){
View child = getChildAt(i);
//测量子View的宽和高
measureChild(child, widthMeasureSpec, heightMeasureSpec);
//得到LayoutParams
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
//子View占据的宽度
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
//子View占据的高度
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
//换行时候
if(lineWidth + childWidth > sizeWidth){
//对比得到最大的宽度
width = Math.max(width, lineWidth);
//重置lineWidth
lineWidth = childWidth;
//记录行高
height += lineHeight;
lineHeight = childHeight;
}else{//不换行情况
//叠加行宽
lineWidth += childWidth;
//得到最大行高
lineHeight = Math.max(lineHeight, childHeight);
}
//处理最后一个子View的情况
if(i == childCount -1){
width = Math.max(width, lineWidth);
height += lineHeight;
}
}
//wrap_content
setMeasuredDimension(modeWidth == MeasureSpec.EXACTLY ? sizeWidth : width,
modeHeight == MeasureSpec.EXACTLY ? sizeHeight : height);
}
/**
* 与当前ViewGroup对应的LayoutParams
*/
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
// TODO Auto-generated method stub
return new MarginLayoutParams(getContext(), attrs);
}
}
这就是自定义布局的流式布局,然后再布局中引用。
2.热搜界面的布局,在这里引用流式布局,显示京东上热搜效果
<LinearLayout 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"
android:orientation="vertical"
tools:context="shouye.presenter.resou.ReSouActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/btn_back"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:text=" < "/>
<EditText
android:id="@+id/et_sou"
android:layout_width="0dp"
android:layout_weight="4"
android:hint="内衣跨店3免1,服装跨店3件7折"
android:layout_height="match_parent" />
<TextView
android:onClick="btn_search"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:text="搜索"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="热搜"
android:textSize="18sp"
android:textStyle="bold"/>
<自己的包名.流式布局的类名
android:id="@+id/reSouView"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="100dp"></自己的包名.流式布局的类名>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="历史记录"
android:textSize="24dp"
/>
<ListView
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="@+id/lv"
></ListView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清空历史记录"
android:layout_gravity="center"
android:gravity="center"
android:onClick="delall"
android:visibility="invisible"
android:id="@+id/btn"
/>
</LinearLayout>
3.在热搜界面进行数据的设置,用greendao增删改查,用eventbus传值
package shouye.presenter.resou;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import org.greenrobot.eventbus.EventBus;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import deom.jingdong.wwx.R;
import deom.jingdong.wwx.dao.DaoMaster;
import deom.jingdong.wwx.dao.DaoSession;
import deom.jingdong.wwx.dao.MySearchBeanDao;
import shouye.model.adapter.GreenDaoAdapter;
import shouye.model.bean.MessageBean;
import shouye.view.SearchActivity;
public class ReSouActivity extends AppCompatActivity {
private static final String TAG = "ReSouActivity";
@BindView(R.id.btn_back)
TextView back;
@BindView(R.id.et_sou)
EditText search_name;
@BindView(R.id.reSouView)
ReSouView reSouView;
@BindView(R.id.lv)
ListView lv;
@BindView(R.id.btn)
Button btn;
private String mNames[] = {
"洗衣机", "娃娃", "山地自行车",
"电冰箱", "水果", "小米手机",
"电脑", "苹果", "三星",
"电磁炉", "vivo", "oppo"};
private MySearchBeanDao beanDao;
private String name;
private MySearchBean mySearchBean;
private List<MySearchBean> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_re_sou);
ButterKnife.bind(this);
//初始化greendao
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(getApplicationContext(), "green_dao.db", null);
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
DaoSession daoSession = daoMaster.newSession();
beanDao = daoSession.getMySearchBeanDao();
//热搜
initChildViews();
//进入就查询展示
inSelect();
//返回
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
//点击条目将值赋给搜索框
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = view.findViewById(android.R.id.text1);
String string = textView.getText().toString();
search_name.setText(string);
Toast.makeText(ReSouActivity.this, string, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 搜索界面回传过来的值
*
* @param messageBean
*/
public void onEventMainThread(MessageBean messageBean) {
search_name.setText(messageBean.getMessage());
}
/**
* 点击删除
*
* @param view
*/
public void delall(View view) {
beanDao.deleteAll();
inSelect();
}
/**
* 点击查询
*
* @param view
*/
public void btn_search(View view) {
name = search_name.getText().toString();
//添加到greendao
mySearchBean = new MySearchBean(null, name);
beanDao.insert(mySearchBean);
Log.i(TAG, "添加的数据是:" + mySearchBean.getName());
//添加之后查询
inSelect();
//eventbus跳转传值
startActivity(new Intent(this, SearchActivity.class));
MessageBean messageBean = new MessageBean();
messageBean.setMessage(name);
//粘性事件传值
EventBus.getDefault().postSticky(messageBean);
}
/**
* 查询出展示数据的方法
*/
private void inSelect() {
//再查询展示出来
list = beanDao.queryBuilder().build().list();
//用baseadapter显示数据
GreenDaoAdapter adapter = new GreenDaoAdapter(this, list);
lv.setAdapter(adapter);
if (list.size() >= 1) {
btn.setVisibility(View.VISIBLE);
}
}
private void initChildViews() {
// TODO Auto-generated method stub
reSouView = findViewById(R.id.reSouView);
ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.leftMargin = 5;
lp.rightMargin = 5;
lp.topMargin = 5;
lp.bottomMargin = 5;
for (int i = 0; i < mNames.length; i++) {
TextView view = new TextView(this);
view.setText(mNames[i]);
view.setTextColor(Color.WHITE);
view.setBackgroundDrawable(getResources().getDrawable(R.drawable.textshape));
reSouView.addView(view, lp);
}
}
}
4.创建一个普通的bean类,通过注解创建SQL数据表。
package shouye.presenter.resou;
import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Property;
/**
* Created by Administrator on 2018/4/28,0028.
*/
@Entity
public class MySearchBean {
@Id(autoincrement = true)
Long id;
@Property
String name;
@Generated(hash = 1426885630)
public MySearchBean() {
}
@Generated(hash = 1256736245)
public MySearchBean(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
5.创建好之后在工具类点击Build里面的Make Pregress 或者(Ctrl+9)自动生成三个类,比如:
6.因为要用EventBus传值,所以在接收值的页面进行EventBus的注册和反注册。
package shouye.view;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
import shouye.model.adapter.GridAdapter;
import shouye.model.adapter.LinearAdapter;
import shouye.model.bean.MessageBean;
import shouye.model.bean.SearchBean;
import deom.jingdong.wwx.R;
import shouye.presenter.SearchPresenter;
import utils.Api;
import shouye.view.IView.ISearchView;
public class SearchActivity extends AppCompatActivity implements ISearchView {
private TextView edit_search;
private CheckBox checkbox;
private RecyclerView recyclerView;
private SearchPresenter searchPresenter;
private String keywords;
private List<SearchBean.DataBean> list;
private LinearAdapter adapter;
private GridAdapter gridadapter;
boolean flag = false;
private TextView back;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
setContentView(R.layout.activity_search);
findView();
//注册EventBus
EventBus.getDefault().register(this);
searchPresenter = new SearchPresenter();
searchPresenter.attachView(this);
keywords = edit_search.getText().toString();
if (keywords == null) {
Toast.makeText(SearchActivity.this, "请输入搜索的内容", Toast.LENGTH_SHORT).show();
} else {
searchPresenter.getData(Api.SEARCH_API, keywords);
}
}
/**
* 将值用EventBus传过来
* @param messageBean
*/
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onRec(MessageBean messageBean) {
edit_search.setText(messageBean.getMessage());
}
private void findView() {
back = findViewById(R.id.search_back);
edit_search = findViewById(R.id.edit_search);
checkbox = findViewById(R.id.checkbox);
recyclerView = findViewById(R.id.reycleView);
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
edit_search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击搜索框回传值
EventBus.getDefault().post(new MessageBean(keywords));
finish();
}
});
}
/**
* 重新的方法
*
* @param dataDataBean
*/
@Override
public void onSuccess(final SearchBean dataDataBean) {
runOnUiThread(new Runnable() {
@Override
public void run() {
list = dataDataBean.getData();
if (dataDataBean.getCode().equals("0")) {
setAdapter(list);
Toast.makeText(SearchActivity.this, dataDataBean.getMsg(), Toast.LENGTH_SHORT).show();
checkbox.setChecked(flag);//默认未点击
checkbox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (flag) {
//设置适配器
setAdapter(list);
checkbox.setChecked(false);
flag = checkbox.isChecked();
} else {
gridadapter = new GridAdapter(SearchActivity.this, list);
recyclerView.setAdapter(gridadapter);
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
checkbox.setChecked(true);
flag = checkbox.isChecked();
//给适配器设置点击事件
gridadapter.setOnItemClick(new LinearAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(SearchActivity.this, "点击" + position, Toast.LENGTH_SHORT).show();
}
});
}
}
});
} else {
Toast.makeText(SearchActivity.this, "输入有误", Toast.LENGTH_SHORT).show();
}
}
});
}
private void setAdapter(List<SearchBean.DataBean> list) {
adapter = new LinearAdapter(SearchActivity.this, list);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(SearchActivity.this, LinearLayoutManager.VERTICAL, false));
//给适配器设置点击事件
adapter.setOnItemClick(new LinearAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
if (searchPresenter != null) {
searchPresenter.dettachView();
}
}
}