京東的熱搜(搜索)界面(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();
    }
}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章