一.自定义搜索历史记录

本地实现搜索历史记录有很多种方法,下面不多说了,我们来用SQLite来实现此功能,直接上完整代码:点击下载源码

效果一:

效果二:

1.MainActivity主函数

package com.example.administrator.searchapplication;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener{private EditText searchContentEt;private SearchRecordsAdapter recordsAdapter;private View recordsHistoryView;private ListView recordsListLv;private TextView clearAllRecordsTv;private LinearLayout searchRecordsLl;private List<String> searchRecordsList;private List<String> tempList;private RecordsDao recordsDao;private TextView tv_history;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initData();bindAdapter();initListener();}private void initView() {
//        setHideHeader();initRecordsView();searchRecordsLl = (LinearLayout) findViewById(R.id.search_content_show_ll);searchContentEt = (EditText) findViewById(R.id.input_search_content_et);tv_history = (TextView) findViewById(R.id.tv_history);//添加搜索viewsearchRecordsLl.addView(recordsHistoryView);}//初始化搜索历史记录Viewprivate void initRecordsView() {recordsHistoryView = LayoutInflater.from(this).inflate(R.layout.search_lishi, null);//显示历史记录lvrecordsListLv = (ListView) recordsHistoryView.findViewById(R.id.search_records_lv);//清除搜索历史记录clearAllRecordsTv = (TextView) recordsHistoryView.findViewById(R.id.clear_all_records_tv);}private void initData() {recordsDao = new RecordsDao(this);searchRecordsList = new ArrayList<>();tempList = new ArrayList<>();tempList.addAll(recordsDao.getRecordsList());reversedList();//第一次进入判断数据库中是否有历史记录,没有则不显示checkRecordsSize();}private void bindAdapter() {recordsAdapter = new SearchRecordsAdapter(this, searchRecordsList);recordsListLv.setAdapter(recordsAdapter);}private void initListener() {clearAllRecordsTv.setOnClickListener(this);searchContentEt.setOnEditorActionListener(new TextView.OnEditorActionListener() {@Overridepublic boolean onEditorAction(TextView v, int actionId, KeyEvent event) {if (actionId == EditorInfo.IME_ACTION_SEARCH) {if (searchContentEt.getText().toString().length() > 0) {String record = searchContentEt.getText().toString();//判断数据库中是否存在该记录
//                        if (!recordsDao.isHasRecord(record)) {
//                            tempList.add(record);
//                        }//将搜索记录保存至数据库中recordsDao.addRecords(record);
//                        reversedList();
//                        checkRecordsSize();
//                        recordsAdapter.notifyDataSetChanged();Toast.makeText(MainActivity.this, "11",Toast.LENGTH_SHORT).show();//根据关键词去搜索} else {Toast.makeText(MainActivity.this, "搜索内容不能为空",Toast.LENGTH_SHORT).show();}}return false;}});//根据输入的信息去模糊搜索searchContentEt.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {if (s.toString().trim().length() == 0) {tv_history.setText("搜索历史");} else {tv_history.setText("搜索结果");}String tempName = searchContentEt.getText().toString();tempList.clear();tempList.addAll(recordsDao.querySimlarRecord(tempName));reversedList();checkRecordsSize();recordsAdapter.notifyDataSetChanged();}});//历史记录点击事件recordsListLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//将获取到的字符串传到搜索结果界面//点击后搜索对应条目内容
//                searchContentEt.setText(searchRecordsList.get(position));Toast.makeText(MainActivity.this,searchRecordsList.get(position)+"",Toast.LENGTH_SHORT).show();searchContentEt.setSelection(searchContentEt.length());}});}//当没有匹配的搜索数据的时候不显示历史记录栏private void checkRecordsSize(){if(searchRecordsList.size() == 0){searchRecordsLl.setVisibility(View.GONE);}else{searchRecordsLl.setVisibility(View.VISIBLE);}}@Overridepublic void onClick(View v) {switch (v.getId()){//清空所有历史数据case R.id.clear_all_records_tv:tempList.clear();reversedList();recordsDao.deleteAllRecords();recordsAdapter.notifyDataSetChanged();searchRecordsLl.setVisibility(View.GONE);searchContentEt.setHint("请输入你要搜索的内容");break;}}//颠倒list顺序,用户输入的信息会从上依次往下显示private void reversedList(){searchRecordsList.clear();for(int i = tempList.size() - 1 ; i >= 0 ; i --) {searchRecordsList.add(tempList.get(i));}}
}

2.SearchRecordsAdapter适配器

package com.example.administrator.searchapplication;/*** Created by Administrator on 2018/2/11.*/import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;import java.util.List;/*** Created by 05 on 2016/7/27.*/
public class SearchRecordsAdapter extends BaseAdapter {private Context context;private List<String> searchRecordsList;private LayoutInflater inflater;public SearchRecordsAdapter(Context context, List<String> searchRecordsList) {this.context = context;this.searchRecordsList = searchRecordsList;inflater = LayoutInflater.from(context);}@Overridepublic int getCount() {//设置listView的显示条目数量为5return searchRecordsList.size() > 5 ? 5 : searchRecordsList.size();}@Overridepublic Object getItem(int position) {return searchRecordsList.size() == 0 ? null : searchRecordsList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if(null == convertView){viewHolder = new ViewHolder();convertView = inflater.inflate(R.layout.list_item,null);viewHolder.recordTv = (TextView) convertView.findViewById(R.id.search_content_tv);convertView.setTag(viewHolder);}else{viewHolder = (ViewHolder) convertView.getTag();}String content = searchRecordsList.get(position);viewHolder.recordTv.setText(content);return convertView;}private class ViewHolder {TextView recordTv;}
}

3.RecordSQLiteOpenHelper

package com.example.administrator.searchapplication;/*** Created by Administrator on 2018/2/11.*/import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;/*** 搜索记录帮助类* Created by 05 on 2016/7/27.*/
public class RecordSQLiteOpenHelper extends SQLiteOpenHelper {private final static String DB_NAME = "temp.db";private final static int DB_VERSION = 1;public RecordSQLiteOpenHelper(Context context) {super(context, DB_NAME, null, DB_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {String sqlStr = "CREATE TABLE IF NOT EXISTS records (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);";db.execSQL(sqlStr);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}

4.RecordsDao

package com.example.administrator.searchapplication;/*** Created by Administrator on 2018/2/11.*/import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;import java.util.ArrayList;
import java.util.List;/*** 搜索记录操作类* Created by 05 on 2016/7/27.*/
public class RecordsDao {RecordSQLiteOpenHelper recordHelper;SQLiteDatabase recordsDb;public RecordsDao(Context context) {recordHelper = new RecordSQLiteOpenHelper(context);}//添加搜索记录public void addRecords(String record) {if (!isHasRecord(record)) {recordsDb = recordHelper.getReadableDatabase();ContentValues values = new ContentValues();values.put("name", record);//添加recordsDb.insert("records", null, values);//关闭recordsDb.close();}}//判断是否含有该搜索记录public boolean isHasRecord(String record) {boolean isHasRecord = false;recordsDb = recordHelper.getReadableDatabase();Cursor cursor = recordsDb.query("records", null, null, null, null, null, null);while (cursor.moveToNext()) {if (record.equals(cursor.getString(cursor.getColumnIndexOrThrow("name")))) {isHasRecord = true;}}//关闭数据库recordsDb.close();cursor.close();return isHasRecord;}//获取全部搜索记录public List<String> getRecordsList() {List<String> recordsList = new ArrayList<>();recordsDb = recordHelper.getReadableDatabase();Cursor cursor = recordsDb.query("records", null, null, null, null, null, null);while (cursor.moveToNext()) {String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));recordsList.add(name);}//关闭数据库recordsDb.close();cursor.close();return recordsList;}//模糊查询public List<String> querySimlarRecord(String record){String queryStr = "select * from records where name like '%" + record + "%' order by name ";List<String> similarRecords = new ArrayList<>();Cursor cursor= recordHelper.getReadableDatabase().rawQuery(queryStr,null);while (cursor.moveToNext()) {String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));similarRecords.add(name);}cursor.close();return similarRecords;}//清空搜索记录public void deleteAllRecords() {recordsDb = recordHelper.getWritableDatabase();recordsDb.execSQL("delete from records");recordsDb.close();}// 删除public int delete(int _id) {SQLiteDatabase db = recordHelper.getWritableDatabase();int d = db.delete("records", "_id=?", new String[] { _id + "" });db.close();return d;}}

5.主函数布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="50dp"><LinearLayoutandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"><ImageViewandroid:layout_width="30dp"android:layout_height="match_parent"android:layout_gravity="center_vertical"android:padding="5dp"android:src="@mipmap/ic_launcher" /><EditTextandroid:id="@+id/input_search_content_et"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入你要搜索的内容"android:imeOptions="actionSearch"android:singleLine="true"/><!-- 以上的singleLine和imeOptions属性代码是将弹出的软键盘的回车键替换成搜索键的关键,当然也可以换成发送键 等等,可以去查一下该属性 --></LinearLayout><TextViewandroid:id="@+id/search_content_cancel_tv"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="center_vertical"android:gravity="center"android:padding="10dp"android:text="取消"android:textSize="18sp" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:orientation="vertical"android:gravity="center|left"android:layout_height="30dp"><TextViewandroid:id="@+id/tv_history"android:layout_width="wrap_content"android:layout_marginLeft="20dp"android:text="搜索历史"android:layout_height="wrap_content" /></LinearLayout><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/search_content_show_ll"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"></LinearLayout></RelativeLayout></LinearLayout>

6.适配器布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:orientation="horizontal"android:layout_width="match_parent"android:layout_height="40dp"><TextViewandroid:id="@+id/search_content_tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:drawableLeft="@mipmap/ic_launcher_round"android:drawablePadding="8dp"android:layout_margin="10dp"android:layout_gravity="center_vertical"/></LinearLayout></LinearLayout>

7.搜索布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="wrap_content"><ListViewandroid:id="@+id/search_records_lv"android:layout_width="match_parent"android:layout_height="wrap_content"/><Viewandroid:layout_width="match_parent"android:layout_height="0.1dp"android:background="@color/colorAccent"/><TextViewandroid:background="@color/colorPrimary"android:id="@+id/clear_all_records_tv"android:layout_width="match_parent"android:layout_height="40dp"android:textSize="16sp"android:gravity="center"android:text="清除历史记录"/><Viewandroid:layout_width="match_parent"android:layout_height="0.1dp"android:background="@color/colorAccent"/></LinearLayout></LinearLayout>
ok,demo资源里有
二.仿bilibili搜索框效果(三句代码实现)

1.添加依赖:
apply plugin: 'com.android.application'android {compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}compileSdkVersion 29buildToolsVersion "29.0.2"defaultConfig {applicationId "com.example.mysgfceshicase"minSdkVersion 15targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}packagingOptions {//解决编译时com.android.builder.merge.DuplicateRelativeFileException: More than one file was found with OS independent path 'META-INF/rxjava.properties'这个错误exclude 'META-INF/rxjava.properties'}
}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'androidx.appcompat:appcompat:1.0.2'implementation 'androidx.constraintlayout:constraintlayout:1.1.3'testImplementation 'junit:junit:4.12'androidTestImplementation 'androidx.test.ext:junit:1.1.0'androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'//noinspection GradleCompatibleimplementation 'com.android.support:recyclerview-v7:26.0.0-beta2'implementation 'com.android.support:cardview' +'-v7:26.0.0-beta2'testImplementation 'junit:junit:4.12'//仿转转轮播图BAnnerimplementation 'com.tokiii:reveal-banner:1.0.1'//下拉刷新、上拉加载、二级刷新、淘宝二楼、RefreshLayout、OverScroll,Android智能下拉刷新框架,支持越界回弹、越界拖动,// 具有极强的扩展性,集成了几十种炫酷的Header和 Footerimplementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0'  //1.0.5及以前版本的老用户升级需谨慎,API改动过大implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0'  //没有使用特殊Header,可以不加这行//炫酷的輪播圖效果implementation 'com.github.ulez:dropindicator:0.0.2'//搜索历史记录implementation 'com.wenwenwen888:searchbox:1.0.1'implementation 'com.jakewharton:butterknife:10.0.0'annotationProcessor 'com.jakewharton:butterknife-compiler:10.0.0'//noinspection GradleCompatibleimplementation 'com.android.support:design:28.0.0'implementation 'io.reactivex:rxandroid:1.1.0'implementation 'io.reactivex:rxjava:1.1.0'
//    implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'
//    implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
//    implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'implementation 'com.trello:rxlifecycle-components:0.6.1'implementation 'com.jakewharton.rxbinding:rxbinding:0.3.0'implementation 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:0.3.0'implementation 'com.jakewharton.rxbinding:rxbinding-design:0.3.0'implementation 'com.github.bumptech.glide:glide:3.7.0'//gradleapi ('com.alibaba.android:ultraviewpager:1.0.7.7@aar') {transitive = true}//首先引入gson库compile 'com.google.code.gson:gson:2.8.1'}
 //搜索历史记录implementation 'com.wenwenwen888:searchbox:1.0.1'

2.主要实现:

//第一句 , 实例化:
SearchFragment searchFragment = SearchFragment.newInstance();//第二句 , 设置回调:
searchFragment.setOnSearchClickListener(new IOnSearchClickListener() {@Overridepublic void OnSearchClick(String keyword) {//这里处理逻辑Toast.makeText(ToolBarActivity.this, keyword, Toast.LENGTH_SHORT).show();}});
//第三句 , 显示搜索框:
searchFragment.showFragment(getSupportFragmentManager(),SearchFragment.TAG);

3.全部代码:

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;import com.example.mysgfceshicase.R;
import com.wyt.searchbox.SearchFragment;
import com.wyt.searchbox.custom.IOnSearchClickListener;import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import butterknife.BindView;
import butterknife.ButterKnife;public class SearchActivity extends AppCompatActivity implements Toolbar.OnMenuItemClickListener, IOnSearchClickListener {@BindView(R.id.toolbar)Toolbar toolbar;@BindView(R.id.search_info)TextView searchInfo;private SearchFragment searchFragment;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_search);ButterKnife.bind(this);toolbar.setTitle("SearchDialog");//标题setSupportActionBar(toolbar);searchFragment = SearchFragment.newInstance();toolbar.setOnMenuItemClickListener(this);searchFragment.setOnSearchClickListener(this);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {//加载菜单文件getMenuInflater().inflate(R.menu.menu_main, menu);return true;}@Overridepublic boolean onMenuItemClick(MenuItem item) {switch (item.getItemId()) {case R.id.action_search://点击搜索searchFragment.showFragment(getSupportFragmentManager(), SearchFragment.TAG);break;}return true;}@Overridepublic void OnSearchClick(String keyword) {searchInfo.setText(keyword);}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.appcompat.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/colorPrimary"app:layout_scrollFlags="scroll|enterAlways" /><TextViewandroid:id="@+id/search_info"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@id/toolbar"android:gravity="center"android:text="Hello Android!"android:textSize="20sp" />
</RelativeLayout>

源码:https://github.com/wenwenwen888/SearchDialog

安卓 本地实现搜索历史记录相关推荐

  1. 本地存储搜索历史记录工具类

    本地存储搜索历史记录 因为需要用到存储本地搜索,所以就提前写一下工具,简单说下分为3部分: 添加搜索记录 获取搜索历史记录 清空搜索记录 基本就是这么回事,代码实现也很简单, #define Reco ...

  2. vue 前端本地存储搜索历史记录,删除某条记录,清空记录

    vue 前端本地保存搜索历史,localStorage 一.保存历史的数组是由元素组成: [ "000004 SZ"] 在页面第一次加载的时候,从localStorage中获取历史 ...

  3. Android实现搜索功能并本地保存搜索历史记录

    本案例实现起来很简单,所以可以直接拿来嵌入项目中使用,涉及到的知识点:  - 数据库的增删改查操作  - ListView和ScrollView的嵌套冲突解决  - 监听软键盘回车按钮设置为搜索按钮  ...

  4. Android搜索功能的案例,本地保存搜索历史记录

    同事负责开发的APP有一个搜索功能,并且需要显示搜索的历史记录,我闲暇之余帮她开发了这个功能,现把该页面抽取成一个demo分享给大家. 实现效果如图所示: 本案例实现起来很简单,所以可以直接拿来嵌入项 ...

  5. 微信小程序—实现搜索功能,搜索历史记录功能

    本文主要基于微信小程序实现和uni-app实现搜索商品和历史记录的功能. 不详细介绍,主看代码注释即可!! 1.搜索组件页面代码块 <template><view><!- ...

  6. 【办公软件篇】Listary搜索神器清除搜索历史记录

    [办公软件篇]Listary搜索神器清除搜索历史记录 装机必备搜索神器-[蘇小沐] 文章目录 [办公软件篇]Listary搜索神器清除搜索历史记录 1.实验环境 (一)删除搜索历史记录 总结 1.实验 ...

  7. 清空计算机搜索文件历史记录,Win10资源管理器怎么清空搜索历史记录?

    Win10系统,在资源管理器的搜索框中输入某文件或文件夹的名称时,即可搜索并显示该文件或文件夹,但搜索完成后,会保留这些搜索条目,且将搜索框条目存储到注册表中供以后参考.此功能对有些朋友来说是有用的, ...

  8. Vue用localStorage保存搜索历史记录/清空记录

    Vue搜索历史记录/清空记录 1.搜索后保存历史记录, localStorage.setItem(key,value) 2.在保存前,先判断数组中是否已存在记录(有:则清除该记录),并将搜索值unsh ...

  9. elementui如何在input 框中搜索_在 Windows 10 中的文件资源管理器中删除搜索历史记录...

    Windows 资源管理器带有搜索功能,用户可以通过该功能找到特定的文件或文件夹.默认情况下,您在搜索框中进行的所有搜索都会保存到其历史记录中.下次您在搜索框中输入内容时,它将在下拉对话框中显示最近输 ...

最新文章

  1. String字符串编码解码格式
  2. 内容生态变现价值凸显,“长期主义者”触宝驶入快车道
  3. BugkuCTF-Misc:come_game
  4. CentOS 7 换yum源
  5. 1044 火星数字 (20 分)(c++)
  6. mysql 7天自动拒单功能,mysql查询最近7天的数据,没有数据自动补0
  7. 程序员的思考--终于确定了自己的技术发展方向
  8. 列表的修改,复制,遍历,嵌套和查询
  9. 敏捷开发般若敏捷系列之三:什么是敏捷(下)(无住,不住于空,破空执,非法,非非法)...
  10. C#——await与async实现多线程异步编程
  11. 【java学习之路】(javaWeb篇)007.正则表达式专题
  12. sql 新增加一列序号_取出上一条下一条的 sql语句
  13. Linux死锁检测-Lockdep
  14. 工业软件研究框架_现在设计一架飞机时会用哪些软件?免费还开源!|莱特湾出品...
  15. 彻底理解nth-child和nth-of-type的区别
  16. 用计算机玩游戏教程,Wegame怎么用手机玩电脑游戏 Wegame手机玩电脑游戏教程
  17. c++求两条直线的交点
  18. 计算机信息系统集成资质涉密信息系统集成资质
  19. 手动清除2345流氓主页小记录以及对过去的一些回忆
  20. CDA Level I 模拟题(3)【附答案解析】

热门文章

  1. python爬虫好友图片_用itchat库爬取你所有微信好友的头像,并合成一张大图
  2. 安卓 修改键盘确定按钮状态,并获取对应点击事件
  3. matlab 三维时频幅值图
  4. mysql订单编号是什么类型_mysql生成订单编号函数
  5. 生活中有什么值得坚持的好习惯?
  6. 计算机视觉和AI | CV小结 | 附资源分享 | 解读技术
  7. 服务器群 密码定期修改,服务器密码设置定期修改密码
  8. 通过国家认定的在线监测仪器_在线监测_环境保护网
  9. 【博客611】linux路由表机制
  10. 柔性电子:基于复合材料的三维互联压电陶瓷薄膜用于机械和热量能量收集