【问题标题】:ArrayAdapter's getView() method getting called automatically on EditText focus eventArrayAdapter 的 getView() 方法在 EditText 焦点事件上自动调用
【发布时间】:2011-10-18 00:04:18
【问题描述】:

我正在创建自定义列表活动。有两个类,一个具有扩展的 ListActivity,另一个具有用于该列表活动的 ArrayAdapter。

问题 1: 问题是,在打开 ListActivity 屏幕时,我在它上面有搜索框。当我启动 ListActivity 时,它会自动打开键盘,因为当前焦点位于 EditText 上。我想阻止它。

问题 2: 此外,当焦点转到 EditText 时,ArrayAdapter 的 getView() 方法会自动调用,这会再次生成所有行。我不明白为什么会这样。我也没有调用 notifyDataSetchanged() 方法。仍然当我专注于 EditText 时,会自动调用 getView()。如何预防?

storelistview.xml:

<?xml version="1.0" encoding="UTF-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/black" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:focusable="true" android:focusableInTouchMode="true">
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <TableRow android:id="@+id/tableRow2" android:layout_height="wrap_content"
            android:gravity="center" android:layout_width="fill_parent"
            android:background="#919191">
                <EditText android:id="@+id/searchText" android:layout_width="fill_parent"
                    android:layout_height="wrap_content" android:width="240dp"
                    android:hint="Search"></EditText>
                <ImageView android:layout_width="wrap_content"
                    android:src="@drawable/search" android:layout_height="wrap_content"
                    android:id="@+id/searchImage"></ImageView>
    </TableRow> 
</TableLayout>
<ListView android:id="@+id/android:list" android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>
<TextView android:id="@+id/android:empty"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:textColor="@color/white" android:textSize="14sp"
    android:gravity="top|center" android:text="No store found.." /></LinearLayout>

StoreListView.java:

public class StoreListView extends ListActivity {

private List<Store> stores = new ArrayList<Store>();
private StoreListRowAdapter rowAdapter;
private Runnable fetchStores;
private Handler handler = new Handler();
private ImageView searchImage;
private EditText searchText;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.storelistview);

    searchText = (EditText) findViewById(R.id.searchText);
    searchImage = (ImageView) findViewById(R.id.searchImage);
    searchImage.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            }

        }
    });

    rowAdapter = new StoreListRowAdapter(this, R.layout.storelistview, stores);
    setListAdapter(rowAdapter);

    fetchStores = new Runnable() {

        @Override
        public void run() {
            Store store = new Store();
            StoreListAsynTask s = new StoreListAsynTask();
            s.execute(store);
        }
    };

    handler.post(fetchStores);

}

private Runnable resultThread = new Runnable() {

    public void run() {
        rowAdapter.clear();
        for (int i = 0; i < stores.size(); i++) {
            Store bean = stores.get(i);
            rowAdapter.add(bean);
        }
        //rowAdapter.notifyDataSetChanged();
    }
};

class StoreListAsynTask extends AsyncTask<Store, Void, String> {

    private Gson gson = new Gson();
    private List<Store> storeList;
    private ProgressDialog m_ProgressDialog = null;

    @Override
    protected String doInBackground(Store... params) {
                 return respData;
    }

    @Override
    protected void onPostExecute(String result) {
                    //populate store list
        stores = storeList;
        runOnUiThread(resultThread);
        m_ProgressDialog.dismiss();
    }

}

}

StoreListRowAdapter.java:

public class StoreListRowAdapter extends ArrayAdapter<Store> {

List<Store> stores;
public StoreListRowAdapter(Context context, int textViewResourceId, List<Store> stores) {
    super(context, textViewResourceId, stores);
    this.stores = stores; 
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;

    if (view == null) {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        view = vi.inflate(R.layout.storelist_rowview, null);
    }

    final Store store = stores.get(position);
    if (store != null) {
        LinearLayout storeLogoContainer = (LinearLayout) view.findViewById(R.id.storeLogoContainer);
        LoaderImageView imageView = new LoaderImageView(getContext(), getContext().getString(R.string.logoUrl), store.getId().getId());
        storeLogoContainer.addView(imageView);

        TextView storeName = (TextView) view.findViewById(R.id.storeName);
        storeName.setText(store.getStoreName());            
    }
    return view;
}

}

【问题讨论】:

    标签: android listview android-arrayadapter


    【解决方案1】:

    当我启动 ListActivity 时,它会自动打开键盘,因为当前焦点位于 EditText 上。我想阻止它。

    那么,把重点放在别的东西上。

    此外,当焦点在 EditText 上时,ArrayAdapter 的 getView() 方法会被自动调用,这会再次生成所有行。

    getView() 被多次调用。它可能会或可能不会“再次生成所有行”。只需确保您的 getView() 实现高效即可。

    如何预防?

    你没有。只需确保您的 getView() 实现高效即可。

    【讨论】:

    • getView() is called lots of times. It may or may not be "generating all rows again". Simply make sure your getView() implementation is efficient. 你能告诉我有什么方法可以让我知道从哪里调用 getView() 吗?我只想在添加一些元素时调用 getView() 并 notifyDataSetChanged()。
    • 实际上,正如您在 getView() 中看到的,有一个图像视图正在从服务器获取图像。现在每次如果 getView() 将被调用,那么它将每次都从服务器获取图像。这在应用程序中是不可接受的。
    • @vbjain:“有什么方法可以让我知道从哪里调用 getView()?” - 不。 “当我添加一些元素和 notifyDataSetChanged() 时,我只想调用 getView()。” -- 你永远不会调用getView(),而当getView() 被调用不是你可以控制的。
    • @vbjain:“这在应用程序中是不可接受的。” -- 然后编写一个更好的应用程序,将您的下载缓存到 RAM/磁盘。无论如何,您都需要该代码,因为用户喜欢滚动他们的列表,而行回收意味着即使在这种情况下,您当前的代码也会“每次都从服务器获取图像”。
    【解决方案2】:

    当我们使用 ArrayAdapter 通过对象数组提供 TextView 时,ARE 会自动调用 toString() 将数组对象转换为需要在 textview 中显示的文本。 但是要使用 TextViews 以外的东西来显示数组,例如 ImageViews,或者要让 toString() 结果之外的一些数据填充视图,我们重写 getView(int, View, ViewGroup) 以返回您想要的视图类型.它由 RE 自动调用..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多