0

I am trying to develop search application with cyrillics. I have one edittext and listview. I would like to search the listview with the content of edittext. I am having custom list view. Here is my code:

Here is the main activity:

package com.searchapplication;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;

import java.util.ArrayList;


public class MainActivity extends ActionBarActivity {

    private LinearLayout llContainer;
    private EditText etSearch;
    private ListView lvProducts;

    private ArrayList<Municipality> mProductArrayList = new ArrayList<Municipality>();
    private MyAdapter adapter1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initialize();
        mProductArrayList.add(new Municipality("1", getResources().getString(R.string.skopje)));
        mProductArrayList.add(new Municipality("2", getResources().getString(R.string.skopska_crna_gora)));
        mProductArrayList.add(new Municipality("3", getResources().getString(R.string.saraj)));
        mProductArrayList.add(new Municipality("4", getResources().getString(R.string.kumanovo)));
        mProductArrayList.add(new Municipality("5", getResources().getString(R.string.kratovo)));

        adapter1 = new MyAdapter(MainActivity.this, mProductArrayList);
        lvProducts.setAdapter(adapter1);

        etSearch.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // Call back the Adapter with current character to Filter

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                adapter1.getFilter().filter(s);
            }
        });
    }

    private void initialize() {
        etSearch = (EditText) findViewById(R.id.etSearch);
        lvProducts = (ListView)findViewById(R.id.lvProducts);
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Here is the code of the model:

package com.searchapplication;
public class Municipality {

    private String id;
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Municipality(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}

Here is my custom adapter:

package com.searchapplication;

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.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;


public class MyAdapter extends BaseAdapter implements Filterable{

    private ArrayList<Municipality> mOriginalValues; // Original Values
    private ArrayList<Municipality> mDisplayedValues;    // Values to be displayed
    LayoutInflater inflater;
    Context context;

    public MyAdapter(Context context, ArrayList<Municipality> mProductArrayList) {
        this.mOriginalValues = mProductArrayList;
        this.mDisplayedValues = mProductArrayList;
        inflater = LayoutInflater.from(context);
        this.context=context;
    }

    @Override
    public int getCount() {
        return mDisplayedValues.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    private class ViewHolder {
        LinearLayout llContainer;
        TextView tvName, tvPrice;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        ViewHolder holder = null;

        if (convertView == null) {

            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.row, null);
            holder.llContainer = (LinearLayout) convertView.findViewById(R.id.llContainer);
            holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tvName.setText(mDisplayedValues.get(position).getName());


        holder.llContainer.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {


            }
        });

        return convertView;
    }

    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {

                mDisplayedValues = (ArrayList<Municipality>) results.values; // has the filtered values
                notifyDataSetChanged();  // notifies the data with new filtered values
            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();        // Holds the results of a filtering operation in values
                ArrayList<Municipality> FilteredArrList = new ArrayList<Municipality>();

                if (mOriginalValues == null) {
                    mOriginalValues = new ArrayList<Municipality>(mDisplayedValues); // saves the original data in mOriginalValues
                }

                /********
                 *
                 *  If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
                 *  else does the Filtering and returns FilteredArrList(Filtered)
                 *
                 ********/
                if (constraint == null || constraint.length() == 0) {

                    // set the Original result to return
                    results.count = mOriginalValues.size();
                    results.values = mOriginalValues;
                } else {
                    constraint = constraint.toString().toLowerCase();
                    for (int i = 0; i < mOriginalValues.size(); i++) {
                        String data = mOriginalValues.get(i).getName();
                        if (data.toString().toLowerCase().contains(constraint)) {
                            FilteredArrList.add(new Municipality(mOriginalValues.get(i).getId(), mOriginalValues.get(i).getName()));
                        }


                    }
                    // set the Filtered result to return
                    results.count = FilteredArrList.size();
                    results.values = FilteredArrList;
                }
                return results;
            }
        };
        return filter;
    }

}

And here is the layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/etSearch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <ListView
        android:id="@+id/lvProducts"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    ></ListView>

</RelativeLayout>

Here is the layout of the row:

<?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"
    android:id="@+id/llContainer">

    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:layout_weight="1"
    />

</LinearLayout>

Here is string resource file:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">SearchApplication</string>

    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="skopje">Скопје</string>
    <string name="skopska_crna_gora">Скопска</string>
    <string name="saraj">Сарај</string>
    <string name="kumanovo">Куманово</string>
    <string name="kratovo">Кратово</string>
    <string name="kriva_palanka">Крива Паланка</string>
    <string name="kicevo">Кичево</string>
    <string name="kamenica">Каменица</string>
    <string name="makedonska_kamenica">Македонска Каменица</string>
    <string name="makedonski_brod">Македонски Брод</string>
    <string name="struga">Струга</string>
    <string name="tetovo">Тетово</string>
    <string name="prefix">скоп</string>
</resources>

The problem is when I type с or ск it is everything ok, but when I type ско there is no result

This piece of code does not return true:

if (data.toString().toLowerCase().contains(constraint))

I am using Macedonian keyboard.

Sergey Glotov
  • 20,200
  • 11
  • 84
  • 98
vikifor
  • 3,426
  • 4
  • 45
  • 75
  • Check out : http://stackoverflow.com/questions/23422072/searchview-in-listview-having-a-custom-adapter/23422665#23422665 – Haresh Chhelana Sep 29 '15 at 12:11
  • The problem comes when I use cyrillics, code works ok when I use latin characters. Do you have an idea? – vikifor Sep 29 '15 at 12:20
  • I think, some characters entered from keyboard (may be "o") don't match with characters in strings.xml, i.e. have different code ("ASCII value"). What value of "o" do you get when you enter it from phone's keyboard? – Sergey Glotov Sep 30 '15 at 15:32
  • I get 111 for o from keyboard,and 65 or something like that from strings.xml – vikifor Sep 30 '15 at 16:52

0 Answers0