我一直在研究一个Android项目,该项目使用三种不同的活动。
它们基本上都是Listviews
。 ListView
未在项目中进行硬编码,而是从数据库中获取的。
我在尝试将搜索功能连接到listview
时遇到麻烦。到目前为止,我已经看过许多教程,它们教如何创建一个ArrayAdapter
与硬编码的Listview
通信,但是我似乎还不知道如何连接它以便从SQL-基于listview
。
我从HERE中发现了一个类似的问题,试图创建一个额外的ArrayAdapter
,但无果而终。
结果是,当我单击搜索栏并尝试键入任何字母以查看实际结果时,它什么也没做。
这是我的MainActivity
package com.example.ragnar.sortiment;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SearchView;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class SortimentActivity extends AppCompatActivity {
List<Sortiment> sortimentMap = new ArrayList<>();
SortimentAdapter sortimentAdapter;
Context thisContext;
EditText edtSearch;
ListView myListView;
ArrayAdapter<String> searchAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sortiment);
Integer selectedStoreId = getIntent().getExtras().getInt("store_id");
edtSearch = (EditText)findViewById(R.id.edtSearch);
myListView = (ListView) findViewById(R.id.storesListView);
searchAdapter = new ArrayAdapter<String>(this,R.layout.list_item);
thisContext = this;
edtSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
SortimentActivity.this.searchAdapter.getFilter().filter(charSequence);
}
@Override
public void afterTextChanged(Editable editable) {
}
});
GetSortimentForStore retrieveData = new GetSortimentForStore();
retrieveData.execute(selectedStoreId);
}
private class GetSortimentForStore extends AsyncTask<Integer,String,String> {
String msg = "";
// JDBC Driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
// Example 10.20.30.40:3306
static final String DB_URL = "jdbc:mysql://" +
DbStrings.DATABASE_URL + "/" +
DbStrings.DATABASE_NAME;
@Override
protected void onPreExecute() {
//progressTextView.setText("Ühendan andmebaasi...");
}
@Override
protected String doInBackground(Integer... selectedStores) {
Connection conn = null;
Statement stmt = null;
try {
Integer selectedStore = selectedStores[0];
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, DbStrings.USERNAME, DbStrings.PASSWORD);
stmt = conn.createStatement();
String sql = "select id, store_id, name, ean, description from myproject.sortiments WHERE store_id = " + selectedStore;
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
Sortiment newSortiment = new Sortiment();
newSortiment.id = rs.getInt("id");
newSortiment.name = rs.getString("name");
newSortiment.store_id = rs.getInt("store_id");
newSortiment.ean = rs.getString("ean");
newSortiment.description = rs.getString("description");
sortimentMap.add(newSortiment);
}
rs.close();
stmt.close();
conn.close();
} catch (SQLException connError) {
msg = "An exception was thrown for JDBC.";
connError.printStackTrace();
} catch (ClassNotFoundException e) {
msg = "A class not found exception was thrown.";
e.printStackTrace();
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(String msg) {
sortimentAdapter = new SortimentAdapter(thisContext, sortimentMap);
myListView.setAdapter(sortimentAdapter);
}
}
}
ListViews的适配器
package com.example.user.sortment;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import java.util.List;
/**
* Created by User on 11.05.2018
*/
public class SortmentAdapter extends BaseAdapter implements Filterable {
LayoutInflater mInflator;
List<Sortiment> map;
public void filterResults(CharSequence filter){
}
public SortimentAdapter(Context c, List<Sortiment> inputMap) {
mInflator = (LayoutInflater)
c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = inputMap;
}
@Override
public int getCount() {
return map.size();
}
@Override
public Object getItem(int position) {
return map.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = mInflator.inflate(R.layout.item_layout,null);
TextView nameTextView = (TextView) v.findViewById(R.id.nameTextView);
TextView priceTextView = (TextView) v.findViewById(R.id.priceTextView);
Sortiment viewObject = map.get(position);
nameTextView.setText(viewObject.name);
//priceTextView.setText(String.format("%.0f", prices.get(position)));
priceTextView.setText(viewObject.ean.toString());
return v;
}
@Override
public Filter getFilter() {
return null;
}
}
和AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.user.sortment">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".StoreActivity" />
<activity android:name=".SortmentActivity"
android:windowSoftInputMode="stateHidden">
</activity>
</application>
</manifest>
还有我的.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context="com.example.user.sortment.MainActivity">
<EditText
android:id="@+id/edtSearch"
android:hint="Search.."
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/storesListView"
android:layout_width="361dp"
android:layout_height="447dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressTextView"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp"
app:layout_constraintHorizontal_bias="0.571"
tools:layout_editor_absoluteY="48dp" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.077"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.081" />
<TextView
android:id="@+id/franchiseTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="TOODE"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@+id/storesListView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.05"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8" />
<TextView
android:id="@+id/EANtextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="EAN"
app:layout_constraintBottom_toTopOf="@+id/storesListView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.841"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8" />
</android.support.constraint.ConstraintLayout>
答案 0 :(得分:2)
您需要在ListView适配器内部创建一个自定义过滤器:
private class ItemFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<Sortiment> list = map;
int count = list.size();
final ArrayList<Sortiment> nlist = new ArrayList<Sortiment>(count);
String filterableString ;
for (int i = 0; i < count; i++) {
filterableString = list.get(i);
if (viewObject.name.toLowerCase().contains(filterString)) {
nlist.add(filterableString);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredData = (ArrayList<Sortiment>) results.values;
notifyDataSetChanged();
}
}
然后在ListView适配器的getFilter(..)
方法中,您需要像上面那样在Adapter类内部返回刚刚创建的自定义过滤器对象:
//Instance variable in your listView Adapter class
private ItemFilter mFilter = new ItemFilter();
@Override
public Filter getFilter() {
return mFilter;
}
PS :在从服务器获取数据时,您还需要显示一个加载器并禁用Search EditText字段。
我希望这会有所帮助。