京东的热搜(搜索)界面(GreenDao,EventBus,Butterknife)

本文详细介绍了如何在Android项目中配置GreenDao, EventBus和Butterknife,并展示了它们在京东热搜界面中的应用。首先在model的build.gradle中添加依赖,然后自定义流失布局,并在热搜界面利用greendao进行数据操作,通过eventbus传递值。文章还提到了bean类的创建以及EventBus的注册和反注册操作。" 40918459,1403318,Eclipse与Tomcat整合快速入门指南,"['Eclipse集成开发环境', 'Tomcat服务器', 'J2EE开发', 'Servlet', 'JSP']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();
    }
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值