【问题标题】:Android: load app icons in a custom adapterAndroid:在自定义适配器中加载应用程序图标
【发布时间】:2014-02-13 12:22:09
【问题描述】:

我正在开发一个新的 Home Launcher,目前它使用列表视图来显示已安装的应用程序。我正在使用自定义适配器来提供应用程序名称和图标。如果我留下应用程序名称,我没有问题,但是,如果我添加图标,列表视图会变得非常缓慢且无法使用。我也尝试过 asynctask,但没有运气。这是我的适配器的相关图片:

public AppInfoAdapter(Context c, List list, ArrayList<String> appList, PackageManager pm, Resources resources) {
    mContext = c;
    mListAppInfo = list;
    mPackManager = pm;
    mAppList = appList;
    mResources = resources;
    activity = (Activity) c;
}

=====

   @Override

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

    View v = convertView;

    if(v == null) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        v = inflater.inflate(R.layout.launcher_adapter_row, null);
    }

    if (v != null) {
        mIcon = (ImageView) v.findViewById(R.id.imageView1);
        tvAppName = (TextView) v.findViewById(R.id.textView1);
    }

    new addItems().execute(tvAppName, mIcon, position);

    return v;
}

====

public class addItems extends AsyncTask<Object, String, Void> {

    private TextView title;
    private ImageView icon;
    private int pos;

    @Override
    protected Void doInBackground(final Object... parameters) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                title = (TextView) parameters[0];
                icon = (ImageView) parameters[1];
                pos = (Integer) parameters[2];

                entry = (ApplicationInfo) mListAppInfo.get(pos);

                icon.setImageDrawable(entry.loadIcon(mPackManager));
                title.setText(entry.loadLabel(mPackManager));
            }
        });

        return null;
    }
}

尝试使用列表视图和网格视图。结果是一样的。由于口吃,滚动是完全不可能的。有什么建议?谢谢

【问题讨论】:

    标签: android android-listview android-asynctask android-adapter baseadapter


    【解决方案1】:

    您再次在 AsynchTask 的 Ui 线程中加载数据,因此请像这样更改您的 AsynchTask..

    public class addItems extends AsyncTask<Object, String, Drawable> {
    
        private TextView title;
        private ImageView icon;
        private int pos;
    
        @Override
        protected Drawable doInBackground(final Object... parameters) {
            title = (TextView) parameters[0];
            icon = (ImageView) parameters[1];
            pos = (Integer) parameters[2];
    
            entry = (ApplicationInfo) mListAppInfo.get(pos);
    
            Drawable drawable = entry.loadIcon(mPackManager);
            return drawable;
        }
    
        @Override
        protected void onPostExecute(Drawable result) {
            super.onPostExecute(result);
            icon.setImageDrawable(result);
            title.setText(entry.loadLabel(mPackManager));
        }
    }
    

    在这里,我在另一个线程中加载 drawable 并将其传递给 onPostexecute,因此 UI 线程上没有开销。在 doInbackGround 方法中设置文本不是一项艰巨的任务。

    【讨论】:

    • 我可以向您报告这方面的问题吗?例如,如果列表滚动到快速:如果我从列表底部快速滚动到顶部,我会得到带有正确图标但名称错误的项目。例如,现在我在列表顶部有 4 个 AdBlock plus,右侧图标:D
    • 在调用Asynchtask之前加载Appname并设置为textview..so删除doinBackground方法中的runonuithread..
    • 我正在用实际更改和一些可能有助于您理解问题的屏幕截图来更新我的答案!
    • 我刚刚用截图更新了我的问题!你能看看吗?谢谢:)
    • 对于读者:这个解决方案很好用!对话中描述的问题是由其他一些与问题点无关的代码引起的!
    【解决方案2】:

    这个说法有问题

    icon.setImageDrawable(entry.loadIcon(mPackManager));
    

    那是因为这个方法 loadIcon() 在 UI 线程中被调用。在 UI 线程上,如果您尝试解码位图,则会在滚动时导致打嗝。

    【讨论】:

      猜你喜欢
      • 2011-07-08
      • 1970-01-01
      • 2015-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-09
      相关资源
      最近更新 更多