【问题标题】:setOnCheckedChangeListener for checkbox in fragmentsetOnCheckedChangeListener 用于片段中的复选框
【发布时间】:2014-03-30 09:35:25
【问题描述】:

所以我对 android 开发还很陌生,我是来学习的。我一直在为列表视图做一些在线教程。

我现在在这个:http://www.survivingwithandroid.com/2013/02/android-listview-adapter-checkbox-item_7.html

现在,我已经按照教程进行了操作,但我自己添加了一些改动。我没有像教程所说的那样在MainActivity 中做所有事情,而是使用片段来扩充我的视图、注册上下文菜单等。fragment 是我的MainActivity.class 中的一个内部类

我在教程中需要在listview 中添加CheckBox。这看起来相当简单,所以我在我的fragmentclass 中实现OnCheckedChangeListener

public class MainActivity extends ActionBarActivity  {  
//PlaceholderFragment is an inner class of MainActivity
    public static class PlaceholderFragment extends Fragment implements android.widget.CompoundButton.OnCheckedChangeListener {

            ListView lv;
            public PlaceholderFragment() {
            }

            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub
                 int pos = lv.getPositionForView(buttonView);
                 System.out.println("Pos ["+pos+"]");


         if (pos != ListView.INVALID_POSITION) {
                 Planet p = planetsList.get(pos);         
                 p.setChecked(isChecked);
        }
        }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container,
            false);
    ListView lv = (ListView) rootView.findViewById(R.id.listView);
    aAdpt = new PlanetAdapter(planetsList, getActivity());
    lv.setAdapter(aAdpt);
    registerForContextMenu(lv);
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

         public void onItemClick(AdapterView<?> parentAdapter, View view, int position,
                                 long id) {


             Toast.makeText(getActivity(), "Item with id ["+id+"] - Position ["+position+"] - Genre ["+aAdpt.getItem(position).getDescr()+"]", Toast.LENGTH_SHORT).show();
         }
    });
    return rootView;
}

在 getView 方法中的 PlanetAdapter.class 中,我有以下代码(根据教程):

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

    PlanetHolder holder = new PlanetHolder();


    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.checkbox_layout, parent, false);

        TextView tv = (TextView) v.findViewById(R.id.name);
        TextView distView = (TextView) v.findViewById(R.id.dist);
        CheckBox chk = (CheckBox) v.findViewById(R.id.chk);

        holder.chk = chk;
        holder.planetNameView = tv;
        holder.distView = distView;
        **chk.setOnCheckedChangeListener((MainActivity) context);** 
        v.setTag(holder);
    }
    else 
        holder = (PlanetHolder) v.getTag();

    Planet p = planetList.get(position);
    holder.planetNameView.setText(p.getName());
    holder.distView.setText("" + p.getDescr());
    holder.chk.setChecked(p.getChecked());


    return v;
} 

}

现在,当我尝试在 Eclipse 上运行代码时,出现错误,因为监听器不再位于 MainActivity chk.setOnCheckedChangeListener((MainActivity) context); - 我已将其移至片段内部类。

现在,我将代码更改为 chk.setOnCheckedChangeListener((MainActivity.PlaceholderFragment) context);,它说我无法从 Context 转换为 MainActivity.PlaceholderFragment

有谁知道我该如何解决这个问题?

【问题讨论】:

    标签: android listview android-fragments android-checkbox


    【解决方案1】:

    改变这个

     chk.setOnCheckedChangeListener((MainActivity) context)
    

     chk.setOnCheckedChangeListener(PlaceholderFragment.this)
    

    您的 Fragment 实现了接口 CompoundButton.OnCheckedChangeListener 而不是您的 Activity

     public static class PlaceholderFragment extends Fragment implements android.widget.CompoundButton.OnCheckedChangeListener {
    

    编辑:

    您似乎在适配器类中有复选框

    所以你需要你的PlanetAdapter 来实现CompoundButton.OnCheckedChangeListener

    改成

    chk.setOnCheckedChangeListener(PlanetAdapter.this);
    

    而且不需要 Fragment 来实现接口。所以改成

    PlaceholderFragment extends Fragment
    

    例子:

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            if (savedInstanceState == null) {
                getFragmentManager().beginTransaction()
                        .replace(R.id.container, new PlaceholderFragment()).commit();
            }
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.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();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    
        /**
         * A placeholder fragment containing a simple view.
         */
        public static class PlaceholderFragment extends Fragment {
    
            public PlaceholderFragment() {
            }
    
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                View rootView = inflater.inflate(R.layout.fragment_main, container,
                        false);
    
                   ApplicationInfo applicationInfo = getActivity().getApplicationInfo();
                    PackageManager pm = getActivity().getPackageManager();
                    List<PackageInfo> pInfo = new ArrayList<PackageInfo>();
                    pInfo.addAll(pm.getInstalledPackages(0));
                    final AppInfo[] app_info = new AppInfo[pInfo.size()];
    
                    int counter = 0;
                    for(PackageInfo item: pInfo){
                        try{
    
                            applicationInfo = pm.getApplicationInfo(item.packageName, 1);
    
                            app_info[counter] = new AppInfo(pm.getApplicationIcon(applicationInfo), 
                                    String.valueOf(pm.getApplicationLabel(applicationInfo)));
    
                            System.out.println(counter);
    
                        }
                        catch(Exception e){
                             e.printStackTrace();
                        }
    
                        counter++;
                    }
    
                ListView listApplication = (ListView)rootView.findViewById(R.id.listView1);
                final AppInfoAdapter adapter = new AppInfoAdapter(getActivity(), app_info);
                listApplication.setAdapter(adapter);
                Button b= (Button)rootView.findViewById(R.id.button1);
                b.setOnClickListener(new OnClickListener()
                {
    
                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
    
                        StringBuilder result = new StringBuilder();
                        for(int i=0;i<app_info.length;i++)
                        {
                            if(adapter.mCheckStates.get(i)==true)
                            {
    
                                               result.append(app_info[i].applicationName);
                                result.append("\n");
                            }
    
                        }
                        Toast.makeText(getActivity(), result, 1000).show();
                    }
    
                });
    
    
                return rootView;
            }
        }
    
    }
    

    AppInfo.java

    public class AppInfo {
        public Drawable icon;
        public String applicationName;
    
        public AppInfo(){
            super();
        }
    
        public AppInfo(Drawable icon, String applicationName){
            super();
            this.icon = icon;
            this.applicationName = applicationName;
        }
    
    
    }
    

    AppInfoAdapter.java

    public class AppInfoAdapter extends ArrayAdapter<AppInfo> implements CompoundButton.OnCheckedChangeListener
    {  SparseBooleanArray mCheckStates; 
    
        Context context;
        AppInfo  data[] = null;
        LayoutInflater mInflater;
        public AppInfoAdapter(Context context, AppInfo[] data){
            super(context, 0,data);
            this.context = context;
            this.data = data;
            mInflater = LayoutInflater.from(context);
            mCheckStates = new SparseBooleanArray(data.length);
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent){
    
            View row = convertView;
            AppInfoHolder holder= null;
    
            if (row == null){
                row = mInflater.inflate(R.layout.list_item, parent, false);
    
                holder = new AppInfoHolder();
    
                holder.imgIcon = (ImageView) row.findViewById(R.id.imageView1);
                holder.txtTitle = (TextView) row.findViewById(R.id.textView1);
                holder.chkSelect = (CheckBox) row.findViewById(R.id.checkBox1);
    
                row.setTag(holder);
    
            }
            else{
                holder = (AppInfoHolder)row.getTag();
            }
    
    
            AppInfo appinfo = data[position];
            holder.txtTitle.setText(appinfo.applicationName);
            holder.imgIcon.setImageDrawable(appinfo.icon);
           // holder.chkSelect.setChecked(true);
            holder.chkSelect.setTag(position);
            holder.chkSelect.setChecked(mCheckStates.get(position, false));
            holder.chkSelect.setOnCheckedChangeListener(this);
            return row;
    
        }
        public boolean isChecked(int position) {
            return mCheckStates.get(position, false);
        }
    
        public void setChecked(int position, boolean isChecked) {
            mCheckStates.put(position, isChecked);
    
        }
    
        public void toggle(int position) {
            setChecked(position, !isChecked(position));
    
        }
    @Override
    public void onCheckedChanged(CompoundButton buttonView,
            boolean isChecked) {
    
         mCheckStates.put((Integer) buttonView.getTag(), isChecked);    
    
    }
    static class AppInfoHolder
    {
        ImageView imgIcon;
        TextView txtTitle;
        CheckBox chkSelect;
    
    }
    }
    

    fragment_main.xml

     <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"
        tools:context="com.example.listviewcheckbox.MainActivity$PlaceholderFragment" >
    
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:text="Button" />
    
        <ListView
            android:id="@+id/listView1"
            android:layout_above="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginTop="16dp" >
        </ListView>
    
    </RelativeLayout>
    

    list_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginLeft="34dp"
            android:layout_marginTop="21dp"
            android:text="TextView" />
    
        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/textView1"
            android:layout_below="@+id/textView1"
            android:layout_marginTop="32dp"
            android:src="@drawable/ic_launcher" />
    
        <CheckBox
            android:id="@+id/checkBox1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_below="@+id/textView1"
            android:layout_marginRight="14dp"
            android:text="CheckBox" />
    
    </RelativeLayout>
    

    activity_main.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.listviewcheckbox.MainActivity"
        tools:ignore="MergeRootFrame" />
    

    捕捉

    【讨论】:

    • 我试过了...但现在错误提示:没有 MainActivity.PlaceholderFragment 类型的封闭实例在范围内可访问
    • 嗨 Raghunandan,您的意思是要查看 setOnCheckedChangeListener 的更新代码吗?我按照你上面写的做了:chk.setOnCheckedChangeListener((PlaceholderFragment.this);
    • @Simon 你的适配器类应该实现接口而不是片段。
    • 有没有更简单的方法来从 Fragment 中获取上下文,就像初始代码如何从 MainActivity 中获取上下文一样?如果我将实现 android.widget.CompoundButton.OnCheckedChangeListener 移动到适配器,这意味着适配器需要实现 onCheckedChanged 方法,并且由于列表视图(lv)在片段视图中,这也意味着 onCreateView 中的代码需要移动以及生成列表视图(我已经更新了上面的代码供您查看)。
    • 不,我没有尝试编辑您的帖子...一定是其他人。
    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 2013-10-21
    • 1970-01-01
    • 2017-11-22
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多