1. 程式人生 > >京東的熱搜(搜尋)介面(GreenDao,EventBus,Butterknife)

京東的熱搜(搜尋)介面(GreenDao,EventBus,Butterknife)

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

}