【问题标题】:Android implementing search in ListFragmentAndroid 在 ListFragment 中实现搜索
【发布时间】:2012-08-08 08:52:24
【问题描述】:

我正在尝试在我的 ListFragment 中添加搜索功能。我已经在标准活动中完成了它,但我试图将它移植到片段中。 我目前正在做的是这样的:

  1. 我有一个托管片段的 Main.java。

  2. 我有一个 ListFrag.java,它使用 R.id.frag_list 托管列表数组 List.TERM

我的 Main.java 像这样实现 addTextChangedListener:

et.addTextChangedListener(new TextWatcher()
    {
    public void afterTextChanged(Editable s)
    {
                                                                    // Abstract Method of TextWatcher Interface.
    }
    public void beforeTextChanged(CharSequence s,
    int start, int count, int after)
    {
    // Abstract Method of TextWatcher Interface.
    }
    public void onTextChanged(CharSequence s,
    int start, int before, int count)
    {
    textlength = et.getText().length();
    array_sort.clear();
    for (int i = 0; i < List.TERM.length; i++)
    {
    if (textlength <= List.TERM[i].length())
    {
    if(et.getText().toString().equalsIgnoreCase(
    (String)
    List.TERM[i].subSequence(0,
    textlength)))
    {array_sort.add(List.TERM[i]);
    }
    }
    }
    lv.setAdapter(new ArrayAdapter<String>
    (Main.this,
            R.layout.main,R.id.frag_list, array_sort));
    }
    });

而我的 main.xml 是这样的:

<LinearLayout
    android:layout_width="fill_parent"
    android:background="@drawable/searchbar"
    android:layout_height="60dp"
    android:layout_marginLeft="15dp"
    android:layout_marginRight="15dp"
    >
    <EditText android:id="@+id/EditText01"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:hint="@string/prompt">
    </EditText>
    </LinearLayout>

<fragment
    android:id="@+id/frag_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
android:layout_marginLeft="50dp"
android:layout_marginTop="90dp"
android:layout_marginBottom="40dp"
    class="com.bernard.ListFrag" />

当我运行应用程序时,我单击了 editText。在我尝试输入字母的那一刻,应用程序崩溃并显示错误日志:

08-11 12:59:57.090: E/AndroidRuntime(20220): FATAL EXCEPTION: main
08-11 12:59:57.090: E/AndroidRuntime(20220): java.lang.NullPointerException
08-11 12:59:57.090: E/AndroidRuntime(20220):    at com.bernard.Main$1.onTextChanged(Main.java:54)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.widget.TextView.sendOnTextChanged(TextView.java:8105)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.widget.TextView.handleTextChanged(TextView.java:8152)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:8532)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.text.SpannableStringBuilder.sendTextChange(SpannableStringBuilder.java:892)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:352)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:266)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:443)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:420)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:29)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:669)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.view.inputmethod.BaseInputConnection.setComposingText(BaseInputConnection.java:431)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:369)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:85)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.os.Looper.loop(Looper.java:156)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at android.app.ActivityThread.main(ActivityThread.java:5025)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at java.lang.reflect.Method.invokeNative(Native Method)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at java.lang.reflect.Method.invoke(Method.java:511)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-11 12:59:57.090: E/AndroidRuntime(20220):    at dalvik.system.NativeStart.main(Native Method)

我对这种错误的猜测是:

  1. 我应该在片段而不是 Main.java 下实现 editText 和文本侦听器。
  2. 我没有从 Main.java 调用新列表,因此会出现 NullPointerException。

有人有解决此问题的建议吗?谢谢:)

【问题讨论】:

  • 你能指出 Main.java 中的哪一行是第 54 行吗?粗略看一下 onTextChanged 会发现有几个地方可能会抛出 NullPointerException,因此如果没有这些信息,很难确定哪个地方实际上是从堆栈跟踪中抛出的。
  • 指的是:lv.setAdapter(new ArrayAdapter(...);

标签: android listview search android-edittext fragment


【解决方案1】:

尝试替换:

for (int i = 0; i < List.TERM.length; i++)
    {
    if (textlength <= List.TERM[i].length())
    {
    if(et.getText().toString().equalsIgnoreCase(
    (String)
    List.TERM[i].subSequence(0,
    textlength)))
    {array_sort.add(List.TERM[i]);
    }
    }
    }
    lv.setAdapter(new ArrayAdapter<String>
    (Main.this,
            R.layout.main,R.id.frag_list, array_sort));
    }
    });

与:

           // reuse the existing adapter instead of creating a new one:
           ArrayAdapter<String> ad = (ArrayAdapter<String>) getListView().getAdapter();
           ad.clear();
           for (int i = 0; i < List.TERM.length; i++) {
              if (textlength <= List.TERM[i].length()) {
                 if (et.getText().toString().equalsIgnoreCase(
                       (String)
                             List.TERM[i].subSequence(0,
                                   textlength))) {
                    ad.add(List.TERM[i]);
                 }
              }
           }
           ad.notifyDataSetChanged(); // tell the ListView to update

【讨论】:

  • 哦,还要确保无论您在哪里实例化 ArrayAdapter,您都在传递一个具体实例,例如 new ArrayList() 作为列表参数。
  • 对上述评论的澄清:如果你只是像许多 ArrayAdapter 教程所示的那样传入一个数组,你会得到一个 ArrayAdapter,它的模型被冻结并且不能被重用,如上所示。
  • 非常感谢您的帮助!对不起,我真的不明白。意思是我应该在 Main.java 或 ListFrag.java 中这样做?在您提出的解决方案的第 2 行中,我得到“方法 getListView() 对于 Main 类型未定义”
  • 我假设 ListFrag.java 扩展了 ListFragment 的类的名称,它将提供对 getListView() 的访问。我现在看到这段代码在 Main.java 中,这让我有点困惑。您可以尝试用您的 lv 变量替换 getListView() ,但没有看到它是如何被初始化的,我怀疑 lv 是否是一个有效的实例。
  • 哈哈,这是我最关心的问题。 Main.java 让我可以访问 R.id.EditText01 但 ListFrag.java 没有。所以我想根据我在 EditText01 中的输入获取一个新列表,并将其传输到 ListFrag。我正在考虑在片段中实现 EditText ......但只是想知道它是否仍然可以在 Main.java 中工作
【解决方案2】:

自己学会了怎么做!也感谢尼克的帮助:D

这有点粗糙,但它确实有效。如果您认为自己有更好的解决方案,请分享!

所以我所做的是根据http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity 中的示例创建一个片段视图列表片段视图

诀窍在于,在 ListFrag.java 中,我只是在 onCreateView 下的原始活动中实现了所有内容。 重要部分如下:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    final View V = inflater.inflate(R.layout.list_fragment, container, false);

    lv = (ListView) V.findViewById(R.id.ListView01);
    final ArrayList <String>ar = new ArrayList<String>();
    et = (EditText) V.findViewById(R.id.EditText01);
    final String[] words = list.TERM;
    // Populate list with our static array of titles.
    lv.setAdapter(new ArrayAdapter<String>(getActivity(),
            android.R.layout.simple_list_item_activated_1, list.TERM));
    lv.setTextFilterEnabled(true); 

    et.addTextChangedListener(new TextWatcher()
    {
    public void afterTextChanged(Editable s)
    {
                                                                    // Abstract Method of TextWatcher Interface.
    }
    public void beforeTextChanged(CharSequence s,
    int start, int count, int after)
    {
    // Abstract Method of TextWatcher Interface.
    }
    public void onTextChanged(CharSequence s,
    int start, int before, int count)
    {
    textlength = et.getText().length();
    array_sort.clear();
    for (int i = 0; i < words.length; i++)
    {
    if (textlength <= words[i].length())
    {
    if(et.getText().toString().equalsIgnoreCase(
    (String)
    words[i].subSequence(0,
    textlength)))
    {array_sort.add(words[i]);
    }
    }
    }
    lv.setAdapter(new ArrayAdapter<String>
    (getActivity(),
            android.R.layout.simple_list_item_activated_1, array_sort));
    }
    });

    //Intent after selection is made
    lv.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            String name = lv.getItemAtPosition(position).toString();
            for (int index = 0; index < words.length; index++)
            {
                if (name.equals(words[index]))
                {
                    position = index;
                    break;
                }
            }
            String d1  = words[position];
            ar.add(d1.toString()); 

            showDetails(position);

        }
    });



    return V;
}

你有它,在片段内的列表视图上进行完整搜索。

【讨论】:

    猜你喜欢
    • 2015-12-26
    • 2017-01-19
    • 1970-01-01
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    相关资源
    最近更新 更多