java - 自定义适配器的异步行为

标签 java android android-adapter

我在我的 Android 应用程序中创建了我自己的自定义适配器类,我从我的一个 Activity 中调用它。我正在从适配器类向 View 添加一些元素,我需要从我的 Activity 类访问这些变量。

现在,理想情况下,我希望它填充 View ,然后在我的 Activity 类中执行更多代码,但是适配器类需要一些时间来填充 View ,同时我的 Activity 类中的更多代码正在执行尚未添加此类元素。 我该如何处理这种情况?我来自js背景。我们在 Java 中有类似 promises 的东西吗?

根据答案,我将代码更改为:

public class HomeActivity extends Activity {

    GridView grid;
    String text[] = {"Calendar","Uber","Weather","News","Youtube","Clock","Email","Maps","Twitter","Facebook"};
    String list_app_name[] = {"calendar","uber","weather","news","youtube","clock","email","maps","twitter","facebook"};
    String id_button[] = {"button_calendar","button_uber","button_weather","button_news","button_youtube","button_clock","button_email","button_maps","button_twitter","button_facebook"};
    int image[] = {R.drawable.social_icons1,R.drawable.social_icons2,R.drawable.social_icons3,R.drawable.social_icons4,
            R.drawable.social_icons5,R.drawable.social_icons6, R.drawable.social_icons7,R.drawable.social_icons8,
            R.drawable.social_icons9,R.drawable.social_icons10};
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_home);

        //setting up the adapter for gridView
        grid = (GridView)findViewById(R.id.simpleGrid);
        ImageAdapter ia = new ImageAdapter(this,image,text,id_button);
        grid.setAdapter(ia);

        ia.notifyDataSetChanged();

        try {
            initStateOfApps();
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    public void initStateOfApps() throws JSONException {
        Log.d("here","here");
        ArrayList<String> list = getEnabledApps();
        Log.d("apps",list.toString());
        for(int i=0;i<list.size();i++) {
            String app_name = list.get(i);

            ToggleButton button=null;
            if(app_name.equals("calendar")) {
                button = (ToggleButton)findViewById(R.id.button_calendar);
                button.setChecked(true);
            } 

        }
    }
}

所以发生的事情是我正在创建一些切换按钮,这些按钮将填充到我编写的 ImageAdapter 类中。 调用 ImageAdapter 后,我会调用适配器上的 notifydatasetchanged() 以更新 View 。 我在适配器内部所做的是为每个切换按钮提供一些我在 res/values/ids.xml 中编写的自定义 ID。 在每个切换按钮上使用 setId 后,我尝试在我的 activity class 中使用该 ID,但它在 中给了我 nullPointerException initStateOfApps() 我正在尝试更改按钮的状态。

因此,即使在使用 notifyDataSetChanged 之后,它的行为仍然相同。

ImageAdapter.java

public class ImageAdapter extends BaseAdapter {
    private Context context;
    private final int item_image[];
    private final String item_text[];
    private final String button_id[];
    public ImageAdapter(Context context, int item_image[], String[] item_text,String[] button) {
        this.context = context;
        this.item_image = item_image;
        this.item_text = item_text;
        this.button_id = button;
    }

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

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View gridView;

        if (convertView == null) {
            gridView = new View(context);

            // get layout from custom_gridview.xml
            gridView = inflater.inflate(R.layout.item, null);

            // set value into imageview
            final ImageView image = (ImageView) gridView.findViewById(R.id.item_image);
            image.setImageResource(item_image[position]);

            // set value into textview
            TextView text = (TextView) gridView.findViewById(R.id.item_text);
            text.setText(item_text[position]);

            final ToggleButton button_ = (ToggleButton) gridView.findViewById(R.id.item_button);

            if(position==0) {
                button_.setId(R.id.button_calendar);
                image.setId(R.id.image_calendar);
            } 


            button_.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener()
            {
                @Override
                public void onCheckedChanged(CompoundButton toggleButton, boolean isChecked)
                {

                    if(context.getResources().getResourceEntryName(toggleButton.getId()).equals("button_calendar")) {
                        if(isChecked) {
                            try {
                                setStateOfApp("calendar","true");
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                            Intent intent = new Intent(context, GoogleApp.class);
                            ((Activity) context).startActivityForResult(intent,10);

                        } else {
                            try {
                                setStateOfApp("calendar","false");
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    } 
                }
            }
        } else {
            gridView = (View) convertView;
        }

        return gridView;
    }
}

最佳答案

您正在尝试访问 View,它不是 Activity 内容 View 的一部分。所以您无法直接访问该 View 。

button = (ToggleButton)findViewById(R.id.button_calendar); // will return null

此 ToggleButton 将为空,因为 findViewById 将无法在当前内容 View 中找到 ToggleButton,因为该 View 存在于您的适配器中而不是内容 View 中。

并且您将收到 nullpointerException,因为您正试图访问 null View 上的属性。

button.setChecked(true); // This button is null

关于java - 自定义适配器的异步行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41813192/

相关文章:

java - 如果我们不知道容器类型中元素的类型,如何实现迭代器?

android - AdMob 广告根本没有显示

android - 签署我的安卓项目

java - 清除并替换 SwipeRefresh 布局上的 ListView 项目

将 MS SQL 2005 DB 与 Tomcat 6 一起使用时出现 Java 内存不足错误

java - 我在使用这个构造函数时遇到问题

java - 为什么前缀类型的 url-pattern 不起作用?(tomcat)

android - 保护 Android Assets 文件夹中的 html/css/js

安卓适配器 : using Linkedlist vs Arraylist

android - RecyclerView OnClick 不工作