搜索ListView不起作用

时间:2018-08-08 07:46:41

标签: android listview searchview

我一直在研究一个Android项目,该项目使用三种不同的活动。 它们基本上都是ListviewsListView未在项目中进行硬编码,而是从数据库中获取的。 我在尝试将搜索功能连接到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>

1 个答案:

答案 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字段。

我希望这会有所帮助。