写这些代码的时候
袁隆平爷爷2021年5月22日13点07分去世的消息
刚好昨天23号是周日,今天补一下
先看图片,你要的是不是这个效果呢
接下来直接贴代码吧,先看布局,
先看布局
<?xml version="1.0" encoding="utf-8"?>
<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=".Mission.ui.missionSearchActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:background="@drawable/item_background"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_margin="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:padding="9dp"
android:src="@mipmap/search_icon"></ImageView>
<EditText
android:imeOptions="actionSearch"
android:singleLine="true"
android:id="@+id/search_edit"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:maxLines="1"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:background="@null"
android:hint="请输入搜索内容"
android:textSize="14dp" />
<ImageView
android:visibility="invisible"
android:id="@+id/iv_delete"
android:src="@drawable/ic_delete"
android:layout_width="30dp"
android:padding="6dp"
android:layout_height="match_parent"/>
</LinearLayout>
<TextView
android:id="@+id/tv_cancel"
android:text="取消"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_hint"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_weight="1"
android:text="搜索历史"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
<ImageView
android:id="@+id/iv_recyclebin"
android:src="@drawable/ic_recyclebin"
android:layout_width="20dp"
android:layout_height="20dp"/>
</LinearLayout>
<View
android:background="#B5b5b5"
android:layout_width="match_parent"
android:layout_height="0.1dp"/>
<com.skyinfor.szls.Util.AutoNewLineLayout
android:id="@+id/anl_history"
android:layout_width="match_parent"
android:layout_height="wrap_content"></com.skyinfor.szls.Util.AutoNewLineLayout>
</LinearLayout>
<com.skyinfor.szls.Util.RefreshLayout
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:dividerHeight="0dp"
android:divider="#ffffff"
android:id="@+id/gv_mission_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:listSelector="@android:color/transparent" />
</com.skyinfor.szls.Util.RefreshLayout>
</LinearLayout>
逻辑部分
public class missionSearchActivity extends AppCompatActivity implements View.OnClickListener, RefreshLayout.OnLoadListener, SwipeRefreshLayout.OnRefreshListener {
private EditText search_edit;
private ArrayList<missionList_C> mission_List_cs = new ArrayList<missionList_C>();
private missionList_C mission_List_c;
private ListView gv_mission_list;
private RefreshLayout swipe_container;
private int last_page = 2;
private int pagenum = 1;
private TextView tv_cancel;
private String MissionSearch;
private AutoNewLineLayout anl_history;
private LinearLayout ll_hint;
private ImageView iv_delete, iv_recyclebin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mission_search);
SystemUtil.setStatusBarColor(this, Color.parseColor("#ffffff"));
SystemUtil.setAndroidNativeLightStatusBar(this, true);
ACache mCache = ACache.get(missionSearchActivity.this); // Fragment里为getActivity()
String MS = mCache.getAsString("mission_search");
System.out.print("MissionSearch::" + MissionSearch);
if(MS==null){
System.out.print("MissionSearch::" + MissionSearch);
}else {
MissionSearch = MS;
//这个是列出来历史搜索的
Message msg = new Message();
msg.what = 26;
Bundle bundle = new Bundle();
bundle.putString("result", MissionSearch);//往Bundle中存放数据
msg.setData(bundle);
Thandler.sendMessage(msg);
}
// Log.e("MissionSearch::",MissionSearch);
InitView();
}
private void InitView() {
iv_recyclebin = findViewById(R.id.iv_recyclebin);
iv_delete = findViewById(R.id.iv_delete);
ll_hint = findViewById(R.id.ll_hint);
anl_history = findViewById(R.id.anl_history);
swipe_container = findViewById(R.id.swipe_container);
swipe_container.setOnRefreshListener(this);
swipe_container.setOnLoadListener(this);
tv_cancel = findViewById(R.id.tv_cancel);
tv_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击取消,直接返回
missionSearchActivity.this.finish();
}
});
iv_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//清空
search_edit.setText("");
ll_hint.setVisibility(View.VISIBLE);
swipe_container.setVisibility(View.GONE);
}
});
//搜索历史的清空按钮,就是页面当中的回收箱
iv_recyclebin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
anl_history.removeAllViews();
ACache mCache = ACache.get(missionSearchActivity.this);
mCache.remove("mission_search");
Toast.makeText(missionSearchActivity.this, "已清理", Toast.LENGTH_SHORT).show();
}
});
gv_mission_list = findViewById(R.id.gv_mission_list);
search_edit = (EditText) findViewById(R.id.search_edit);
//输入框软键盘的搜索监听
search_edit.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
//点击搜索的时候隐藏软键盘
// 在这里写搜索的操作,一般都是网络请求数据
· GetTaskList(search_edit.getText().toString());//这个是获取接口解析的,这个得自己根据情况来写
//点击搜索,隐藏该布局
ll_hint.setVisibility(View.GONE);
swipe_container.setVisibility(View.VISIBLE);
//点击搜索后,存入缓存
ACache mCache = ACache.get(missionSearchActivity.this); // Fragment里为getActivity()
// MissionSearch = mCache.getAsString("mission_search");
String mission_search = mCache.getAsString("mission_search");
if (mission_search == null) {
mCache.put("mission_search", search_edit.getText().toString());
} else {
if (mission_search.contains(search_edit.getText().toString())) {
//如果包含,就不再存了
} else {
mCache.put("mission_search", MissionSearch + "," + search_edit.getText().toString());
}
}
return true;
}
return false;
}
});
//这个是搜索框里面的黑叉叉,用来清空搜索内容的,同时会显示历史搜索
search_edit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//写入前判断是否有文字
if (search_edit.getText().toString().equals("")) {
iv_delete.setVisibility(View.INVISIBLE);
} else {
iv_delete.setVisibility(View.VISIBLE);
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
//写入前判断是否有文字
if (search_edit.getText().toString().equals("")) {
iv_delete.setVisibility(View.INVISIBLE);
} else {
iv_delete.setVisibility(View.VISIBLE);
}
}
});
}
//更新ui用的
private Handler Thandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 26:
String result26 = msg.getData().getString("result");//接受msg传递过来的参数
System.out.println("Handler::::" + result26);
//解析到
if(result26.contains(",")){
String[] str = result26.split(",");
for (String string : str) {
//逐个new出来
newTextview(missionSearchActivity.this, string);
}
}else {
newTextview(missionSearchActivity.this, result26);
}
break;
}
}
};
/*
* new控件
* */
private void newTextview(Context context, String str) {
//设置大小
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
LinearLayout project = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.item_searchhistory, null);
project.setLayoutParams(lp);
LinearLayout ll_history = (LinearLayout) project.findViewById(R.id.ll_history);
TextView tv_history = (TextView) ll_history.findViewById(R.id.tv_history);
tv_history.setText(str);
tv_history.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GetTaskList(tv_history.getText().toString());
//点击搜索,隐藏该布局
ll_hint.setVisibility(View.GONE);
swipe_container.setVisibility(View.VISIBLE);
search_edit.setText(tv_history.getText().toString());
}
});
anl_history.addView(project);
}
@Override
public void onClick(View v) {
}
//上拉加载,下拉刷新
@Override
public void onRefresh() {
String str = search_edit.getText().toString();
GetTaskList(str);
swipe_container.setRefreshing(false);
}
@Override
public void onLoad() {
if (pagenum < last_page) {
int num = ++pagenum;
String str = search_edit.getText().toString() + "&page=" + num;
GetTaskList(str);
swipe_container.setLoading(false);
} else {
}
}
}
自动换行布局
/**
* 描述:自动换行Layout
*/
public class AutoNewLineLayout extends ViewGroup {
/**
* 两个子控件之间的横向间隙
*/
protected float horizontalSpace = 0;
/**
* 两个子控件之间的垂直间隙
*/
protected float vertivalSpace = 0;
public AutoNewLineLayout(Context context) {
this(context, null, 0);
}
public AutoNewLineLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoNewLineLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.AutoNewLineLayout);
horizontalSpace = ta.getDimension(R.styleable.AutoNewLineLayout_horizontalSpace1, 0);
vertivalSpace = ta.getDimension(R.styleable.AutoNewLineLayout_vertivalSpace1, 0);
ta.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
//AT_MOST
int width = 0;
int height = 0;
int rawWidth = 0;//当前行总宽度
int rawHeight = 0;// 当前行高
int rowIndex = 0;//当前行位置
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if(child.getVisibility() == GONE){
if(i == count - 1){
//最后一个child
height += rawHeight;
width = Math.max(width, rawWidth);
}
continue;
}
//这里调用measureChildWithMargins 而不是measureChild
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
if(rawWidth + childWidth + (rowIndex > 0 ? horizontalSpace : 0)> widthSpecSize - getPaddingLeft() - getPaddingRight()){
//换行
width = Math.max(width, rawWidth);
rawWidth = childWidth;
height += rawHeight + vertivalSpace;
rawHeight = childHeight;
rowIndex = 0;
} else {
rawWidth += childWidth;
if(rowIndex > 0){
rawWidth += horizontalSpace;
}
rawHeight = Math.max(rawHeight, childHeight);
}
if(i == count - 1){
width = Math.max(rawWidth, width);
height += rawHeight;
}
rowIndex++;
}
setMeasuredDimension(
widthSpecMode == MeasureSpec.EXACTLY ? widthSpecSize : width + getPaddingLeft() + getPaddingRight(),
heightSpecMode == MeasureSpec.EXACTLY ? heightSpecSize : height + getPaddingTop() + getPaddingBottom()
);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int viewWidth = r - l;
int leftOffset = getPaddingLeft();
int topOffset = getPaddingTop();
int rowMaxHeight = 0;
int rowIndex = 0;//当前行位置
View childView;
for( int w = 0, count = getChildCount(); w < count; w++ ){
childView = getChildAt(w);
if(childView.getVisibility() == GONE) continue;
MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
// 如果加上当前子View的宽度后超过了ViewGroup的宽度,就换行
int occupyWidth = lp.leftMargin + childView.getMeasuredWidth() + lp.rightMargin;
if(leftOffset + occupyWidth + getPaddingRight() > viewWidth){
leftOffset = getPaddingLeft(); // 回到最左边
topOffset += rowMaxHeight + vertivalSpace; // 换行
rowMaxHeight = 0;
rowIndex = 0;
}
int left = leftOffset + lp.leftMargin;
int top = topOffset + lp.topMargin;
int right = leftOffset+ lp.leftMargin + childView.getMeasuredWidth();
int bottom = topOffset + lp.topMargin + childView.getMeasuredHeight();
childView.layout(left, top, right, bottom);
// 横向偏移
leftOffset += occupyWidth;
// 试图更新本行最高View的高度
int occupyHeight = lp.topMargin + childView.getMeasuredHeight() + lp.bottomMargin;
if(rowIndex != count - 1){
leftOffset += horizontalSpace;
}
rowMaxHeight = Math.max(rowMaxHeight, occupyHeight);
rowIndex++;
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
@Override
protected LayoutParams generateLayoutParams(LayoutParams p) {
return new MarginLayoutParams(p);
}
}
记得还有一个listview的上拉加载下拉刷新的
/**
* 继承自SwipeRefreshLayout,从而实现滑动到底部时上拉加载更多的功能.
*/
public class RefreshLayout extends SwipeRefreshLayout implements
GridView.OnScrollListener {
/**
* 滑动到最下面时的上拉操作
*/
private int mTouchSlop;
/**
* listview实例
*/
private ListView mListView;
/**
* 上拉监听器, 到了最底部的上拉加载操作
*/
private OnLoadListener mOnLoadListener;
/**
* ListView的加载中footer
*/
private View mListViewFooter;
/**
* 按下时的y坐标
*/
private int mYDown;
/**
* 抬起时的y坐标, 与mYDown一起用于滑动到底部时判断是上拉还是下拉
*/
private int mLastY;
/**
* 是否在加载中 ( 上拉加载更多 )
*/
private boolean isLoading = false;
/**
* @param context
*/
public RefreshLayout(Context context) {
this(context, null);
}
@SuppressLint("InflateParams")
public RefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mListViewFooter = LayoutInflater.from(context).inflate(
R.layout.layout_footer_view, null, false);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
// 初始化ListView对象
if (mListView == null) {
getListView();
}
}
/**
* 获取ListView对象
*/
private void getListView() {
int childs = getChildCount();
if (childs > 0) {
View childView = getChildAt(0);
if (childView instanceof ListView) {
mListView = (ListView) childView;
// 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载
mListView.setOnScrollListener(this);
Log.d(VIEW_LOG_TAG, "### 找到listview");
}
}
}
/*
* (non-Javadoc)
*
* @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// 按下
mYDown = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
// 移动
mLastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
// 抬起
if (canLoad()) {
loadData();
}
break;
default:
break;
}
try {
return super.dispatchTouchEvent(event);
}catch(Exception e){
return false;
}
}
/**
* 是否可以加载更多, 条件是到了最底部, listview不在加载中, 且为上拉操作.
*
* @return
*/
private boolean canLoad() {
return isBottom() && !isLoading && isPullUp();
}
/**
* 判断是否到了最底部
*/
private boolean isBottom() {
if (mListView != null && mListView.getAdapter() != null) {
return mListView.getLastVisiblePosition() == (mListView
.getAdapter().getCount() - 1);
}
return false;
}
/**
* 是否是上拉操作
*
* @return
*/
private boolean isPullUp() {
return (mYDown - mLastY) >= mTouchSlop;
}
/**
* 如果到了最底部,而且是上拉操作.那么执行onLoad方法
*/
private void loadData() {
if (mOnLoadListener != null) {
// 设置状态
setLoading(true);
//
mOnLoadListener.onLoad();
}
}
/**
* @param loading
*/
public void setLoading(boolean loading) {
isLoading = loading;
if (isLoading) {
mListView.addFooterView(mListViewFooter);
} else {
mListView.removeFooterView(mListViewFooter);
mYDown = 0;
mLastY = 0;
}
}
/**
* @param loadListener
*/
public void setOnLoadListener(OnLoadListener loadListener) {
mOnLoadListener = loadListener;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// 滚动时到了最底部也可以加载更多
if (canLoad()) {
loadData();
}
}
/**
* 设置刷新
*/
public static void setRefreshing(SwipeRefreshLayout refreshLayout,
boolean refreshing, boolean notify) {
Class<? extends SwipeRefreshLayout> refreshLayoutClass = refreshLayout
.getClass();
if (refreshLayoutClass != null) {
try {
Method setRefreshing = refreshLayoutClass.getDeclaredMethod(
"setRefreshing", boolean.class, boolean.class);
setRefreshing.setAccessible(true);
setRefreshing.invoke(refreshLayout, refreshing, notify);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* 加载更多的监听器
*/
public static interface OnLoadListener {
public void onLoad();
}
}