自定义View 流式布局(历史搜索,热门搜索)
程序员文章站
2022-07-13 15:30:12
...
xml布局
<?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="wrap_content"
tools:context=".activity.SearchActivity"
android:orientation="vertical"
>
<bawei.com.week2.customview.HeadView
android:id="@+id/head_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"></bawei.com.week2.customview.HeadView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<bawei.com.week2.customview.TitleView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginLeft="30dp"
app:textColor="@color/colorBlack"
android:text="搜索历史"
android:textSize="25sp"
/>
<ImageView
android:id="@+id/image_del"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/del"
android:layout_alignParentRight="true"
android:layout_marginTop="30dp"
/>
</RelativeLayout>
<bawei.com.week2.customview.CustonFlowView
android:id="@+id/flow_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginLeft="30dp"
></bawei.com.week2.customview.CustonFlowView>
<bawei.com.week2.customview.TitleView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginLeft="30dp"
app:textColor="@color/colorRed"
android:text="热门搜索"
android:textSize="25sp"
/>
<bawei.com.week2.customview.CustonFlowView
android:id="@+id/hot_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginLeft="30dp"
></bawei.com.week2.customview.CustonFlowView>
</LinearLayout>
HeadView的布局(headitem)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/imageview"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/search"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
/>
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="10dp"
android:ems="20"
android:hint="请输入想要输入的内容"
/>
</LinearLayout>
HeadView代码
public class HeadView extends LinearLayout {
private Context mContext;
private ImageView imageView;
private EditText editText;
public HeadView(Context context) {
super(context);
mContext=context;
initView();
}
public HeadView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext=context;
initView();
}
public void initView(){
//添加布局
View view=View.inflate(mContext,R.layout.headitem,null);
//获取资源ID
imageView = view.findViewById(R.id.imageview);
editText = view.findViewById(R.id.edit_text);
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//6.在将要判断的地方,判断是否为空
if(mCallBack!=null){
//7.执行回调方法,传入参数
mCallBack.getData(editText.getText().toString());
}
}
});
addView(view);
}
//3.定义成员变量
CallBack mCallBack;
//4.传入,并且给成员变量赋值
//5.在想要的地方进行回调
public void setOnCallBack(CallBack callBack){
mCallBack=callBack;
}
//1.定义接口
public interface CallBack{
//2.定义方法,传入参数
void getData(String edit);
}
}
自定义属性在values下建一个attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TitleView">
<attr name="textColor" format="color"></attr>
</declare-styleable>
</resources>
TitleView代码(自定义属性)
@SuppressLint("AppCompatCustomView")
public class TitleView extends TextView {
public TitleView(Context context) {
super(context);
}
public TitleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleView);
int color = typedArray.getColor(R.styleable.TitleView_textColor, Color.BLACK);
setTextColor(color);
//属性回收
typedArray.recycle();
}
}
CustonFlowView中的代码
public class CustonFlowView extends LinearLayout {
private int mChildHeight;//最高的孩子
private int mLeft=20;//左边距
private int mTop=20; //上边距
public CustonFlowView(Context context) {
super(context);
}
public CustonFlowView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//定义父窗口的宽高
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//测量孩子的大小
measureChildren(widthMeasureSpec,heightMeasureSpec);
//找到最高的孩子
findMaxHeight();
//初始化
int left=0,top=0;
int childCount = getChildCount();
for (int i=0;i<childCount;i++){
View view = getChildAt(i);
if(left!=0){
if((left+view.getMeasuredWidth())>widthSize){
top+=mChildHeight+mTop;
left=0;
}
}
left+=view.getMeasuredWidth()+mLeft;
}
setMeasuredDimension(widthSize,(top+mChildHeight)>heightSize?heightSize:top+mChildHeight);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
findMaxHeight();
//初始化
int left=0,top=0;
int childCount = getChildCount();
for (int i=0;i<childCount;i++){
View view = getChildAt(i);
if(left!=0){
if((left+view.getMeasuredWidth())>getWidth()){
top+=mChildHeight+mTop;
left=0;
}
}
view.layout(left,top,view.getMeasuredWidth()+left,top+mChildHeight);
left+=view.getMeasuredWidth()+mLeft;
}
}
private void findMaxHeight() {
mChildHeight=0;
int childCount = getChildCount();
for(int i=0;i<childCount;i++){
View view = getChildAt(i);
if(view.getMeasuredHeight()>mChildHeight){
mChildHeight=view.getMeasuredHeight();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
}
数据库
SqlieHelper
public class SqliteHelper extends SQLiteOpenHelper {
public SqliteHelper(@Nullable Context context) {
super(context, "Search.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table search(id integer primary key autoincrement," +
"name text," +
"mTag text)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
数据库中查询用到的bean类
public class NameBean {
public String name;
public String mTag;
public NameBean(String name, String mTag) {
this.name = name;
this.mTag = mTag;
}
public String getName() {
return name;
}
public String getmTag() {
return mTag;
}
}
Dao层
public class Dao {
private SqliteHelper helper;
private SQLiteDatabase database;
public Dao(Context context){
helper=new SqliteHelper(context);
database=helper.getReadableDatabase();
}
//添加
public void add(String name,String mTag){
ContentValues values=new ContentValues();
values.put("name",name);
values.put("mTag",mTag);
database.insert("search",null,values);
}
//查询
public List<NameBean> select(){
List<NameBean> list=new ArrayList<>();
Cursor query = database.query("search", null, null, null, null, null, null);
while (query.moveToNext()){
String name = query.getString(query.getColumnIndex("name"));
String mTag = query.getString(query.getColumnIndex("mTag"));
NameBean bean=new NameBean(name,mTag);
list.add(bean);
}
return list;
}
//删除
public void delAll(){
database.delete("search",null,null);
}
public void del(String tj){
database.delete("search","mTag=?",new String[]{tj});
}
}
Activity中的代码
public class SearchActivity extends AppCompatActivity {
private HeadView headView;
private CustonFlowView custonFlowView;
private CustonFlowView hot_view;
private String str[]=new String[]{"辣条","薯片","火腿肠","酸辣粉","米线","奶茶嫁给粉","麻辣烫","黄焖鸡","大虾","酸菜鱼"};
private Dao dao;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
initView(savedInstanceState);
initData();
}
private void initData() {
dao=new Dao(this);
//查询
final List<NameBean> list = dao.select();
for(int i=0;i<list.size();i++){
TextView textView=new TextView(SearchActivity.this);
textView.setText(list.get(i).getName());
textView.setTextSize(20);
textView.setTextColor(Color.BLACK);
textView.setPadding(10,10,10,10);
textView.setBackgroundResource(R.drawable.shape_text);
custonFlowView.addView(textView);
//删除
final int index=i;
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dao.del(list.get(index).getmTag());
custonFlowView.removeView(v);
}
});
}
headView.setOnCallBack(new HeadView.CallBack() {
@Override
public void getData(String edit) {
String uuid = UUID.randomUUID().toString();
final TextView textView=new TextView(SearchActivity.this);
textView.setTag(uuid);
textView.setText(edit);
textView.setTextSize(20);
textView.setTextColor(Color.BLACK);
textView.setPadding(10,10,10,10);
textView.setBackgroundResource(R.drawable.shape_text);
dao.add(edit,uuid);
custonFlowView.addView(textView);
//删除
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dao.del(v.getTag().toString());
custonFlowView.removeView(v);
}
});
}
});
//全部删除
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dao.delAll();
custonFlowView.removeAllViews();
}
});
//热门搜索
for (int i=0;i<str.length;i++){
TextView textView=new TextView(SearchActivity.this);
textView.setText(str[i]);
textView.setTextSize(20);
textView.setTextColor(Color.BLACK);
textView.setPadding(10,10,10,10);
textView.setBackgroundResource(R.drawable.shape_text);
hot_view.addView(textView);
}
}
private void initView(Bundle savedInstanceState) {
headView = findViewById(R.id.head_view);
custonFlowView = findViewById(R.id.flow_view);
hot_view = findViewById(R.id.hot_view);
imageView = findViewById(R.id.image_del);
}
}
shape
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:radius="20dp"
></corners>
<stroke
android:width="1dp"
android:color="@color/colorPrimary"
></stroke>
</shape>
上一篇: 自定义View画圆
下一篇: 自定义View 之 圆形