2017-03-10 27 views
0

我目前正在尝试做一个简单的任务杀手为学习目的,我创建了一个列表视图,显示所有用户安装的应用程序与复选框,所以用户可以选择与应用程序应该在屏幕关闭时被杀死。保存状态动态创建复选框

但我停留在如何保存复选框状态,并得到检查应用的软件包名称

我有搜索栈溢出了很长时间,但还是不知道该怎么做,请帮帮我,谢谢

这是我的代码

AppAdapter.java

public class AppAdapter extends BaseAdapter { 

private LayoutInflater layoutInflater; 
private List<AppList> listStorage; 

public AppAdapter(Context context, List<AppList> customizedListView) { 
    layoutInflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    listStorage = customizedListView; 
} 

@Override 
public int getCount() { 
    return listStorage.size(); 
} 

@Override 
public Object getItem(int position) { 
    return position; 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 

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

    final ViewHolder listViewHolder; 
    if(convertView == null){ 
     listViewHolder = new ViewHolder(); 
     convertView = layoutInflater.inflate(R.layout.installed_app_list, parent, false); 

     listViewHolder.textInListView = (TextView)convertView.findViewById(R.id.list_app_name); 
     listViewHolder.imageInListView = (ImageView)convertView.findViewById(R.id.app_icon); 
     listViewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkBox); 
     convertView.setTag(listViewHolder); 

     listViewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      @Override 
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
       if(isChecked){ 
        listViewHolder.checkBox.setSelected(listStorage.get(position).isSelected()); 
       } 
      } 
     }); 
    }else{ 
     listViewHolder = (ViewHolder)convertView.getTag(); 
    } 
    listViewHolder.textInListView.setText(listStorage.get(position).getName()); 
    listViewHolder.imageInListView.setImageDrawable(listStorage.get(position).getIcon()); 
    listViewHolder.checkBox.setChecked(listStorage.get(position).isSelected()); 

    return convertView; 
} 

static class ViewHolder{ 

    TextView textInListView; 
    ImageView imageInListView; 
    CheckBox checkBox; 
} 

}

Applist.java

public class AppList { 

private String name; 
Drawable icon; 
private static final String PREFERENCES_NAMESPACE = "checkboxes_states"; 
boolean selected = false; 
private SharedPreferences mSettings; 
private SharedPreferences.Editor mEditor; 

public AppList(Context context, String name, Drawable icon) { 
    this.name = name; 
    this.icon = icon; 
    mSettings = context.getSharedPreferences(PREFERENCES_NAMESPACE, 0); 
    mEditor = mSettings.edit(); 
    setSelected(mSettings.getBoolean(name, selected)); 
} 

public String getName() { 
    return name; 
} 

public Drawable getIcon() { 
    return icon; 
} 
public boolean isSelected() { 
    return selected; 
} 
public void setSelected(boolean selected) { 
    if(this.selected != selected) { // update if changed 
     mEditor.putBoolean(getName(), selected); 
     mEditor.apply(); 
     this.selected = selected; 
    } 
} 
} 

MainActivity.java

public class MainActivity extends Activity { 

Context context; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    context = getApplicationContext(); 

    ListView userInstalledApps = (ListView)findViewById(R.id.installed_app_list); 

    List<AppList> installedApps = getInstalledApps(); 
    AppAdapter installedAppAdapter = new AppAdapter(MainActivity.this, installedApps); 
    userInstalledApps.setAdapter(installedAppAdapter); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

private List<AppList> getInstalledApps() { 
    List<AppList> res = new ArrayList<AppList>(); 
    List<PackageInfo> packs = getPackageManager().getInstalledPackages(0); 
    for (int i = 0; i < packs.size(); i++) { 
     PackageInfo p = packs.get(i); 
     if ((isSystemPackage(p) == false)) { 
      String appName = p.applicationInfo.loadLabel(getPackageManager()).toString(); 
      Drawable icon = p.applicationInfo.loadIcon(getPackageManager()); 
      res.add(new AppList(context, appName, icon)); 
     } 
    } 
    return res; 
} 

private boolean isSystemPackage(PackageInfo pkgInfo) { 
    return ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ? true : false; 
} 
} 

在此先感谢

回答

1

创建界面:

public interface AppSelector { 
     void selectApp(String appName); 
     void removeApp(String appName); 
     boolean isSelected(String appName); 
    } 

将它添加到您的AppAdapter:

public class AppAdapter extends BaseAdapter { 

    private AppSelector appSelector; 
    private List<AppList> listStorage; 

    public AppAdapter(AppSelector appSelector, List<AppList> customizedListView) { 
     this.appSelector = appSelector; 
     listStorage = customizedListView; 
    } 

    .... 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     final ViewHolder listViewHolder; 
     if(convertView == null){ 
      listViewHolder = new ViewHolder(); 
      convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.installed_app_list, parent, false); 

      listViewHolder.textInListView = (TextView)convertView.findViewById(R.id.list_app_name); 
      listViewHolder.imageInListView = (ImageView)convertView.findViewById(R.id.app_icon); 
      listViewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkBox); 
      convertView.setTag(listViewHolder); 
      listViewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
       @Override 
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
        if (isChecked) { 
         appSelector.selectApp(listStorage.get(position).getName()); 
        } else { 
         appSelector.removeApp(listStorage.get(position).getName()); 
        } 
       } 
      }); 
     } else { 
      listViewHolder = (ViewHolder)convertView.getTag(); 
     } 
     listViewHolder.textInListView.setText(listStorage.get(position).getName()); 
     listViewHolder.imageInListView.setImageDrawable(listStorage.get(position).getIcon()); 
     listViewHolder.checkBox.setChecked(appSelector.isSelected(listStorage.get(position).getName())); 

     return convertView; 
    } 

    .... 
} 

实现您的MainActivity:

class MainActivity extends AppCompatActivity implements AppSelector { 

    private static final String PREFERENCES_NAMESPACE = "checkboxes_states"; 
    private SharedPreferences checkedAppsPreferences; 

    .... 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     .... 
     checkedAppsPreferences = getSharedPreferences(PREFERENCES_NAMESPACE, 0); 
     .... 
     AppAdapter installedAppAdapter = new AppAdapter(this, installedApps); 
     .... 
    } 

    @Override 
    public void selectApp(String appName) { 
     checkedAppsPreferences.edit() 
      .putBoolean(appName, true) 
      .apply(); 
    } 

    @Override 
    public void removeApp(String appName) { 
     checkedAppsPreferences.edit() 
      .remove(appName) 
      .apply(); 
    } 

    @Override 
    public boolean isSelected(String appName) { 
     return checkedAppsPreferences.contains(appName) && checkedAppsPreferences.getBoolean(appName, false); 
    } 

    .... 
} 

您的AppList类不应包含任何对Context或SharedPreferences的引用以及“检查”/“取消选中”的逻辑。它应该是简单的POJO。

使用接口可以方便的与另一种库像SQLite的

EDITED替换共享偏好:我改变AppAdapter getView mwthod:

  listViewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
      @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
       if (isChecked) { 
        appSelector.selectApp(listStorage.get(position).getName()); 
       } else { 
        appSelector.removeApp(listStorage.get(position).getName()); 
       } 
      } 
     }); 

您可以在https://github.com/valeragit/AppListExample

+0

我试过你的代码但没有工作,该复选框仍然没有保存状态 – Dragon957

+0

编辑,虽然添加测试项目 –

+0

我尝试导入您的项目和测试应用程序,但它仍然无法正常工作,滚动listview后,复选框变得不再检查 – Dragon957

1

你从没叫过AppList.setSelected()。 调用listViewHolder onClickListener时,然后probaby通知适配器有更改。 你也可能要调用setChecked而非的setSelected

listViewHolder.checkBox.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       boolean isSelected = listStorage.get(position).isSelected(); 
       listViewHolder.checkBox.setChecked(!isSelected); 
       listStorage.get(position).setSelected(!isSelected) 
       notifyDataSetChanged(); 
      } 
     }); 

您可以进一步通过设置checkChangedListener而不是onClickListener改善这一点,但首先要解决的首要问题。

编辑:OP解决了最初的问题,现在评论改进。 替换的onClick本:

listViewHolder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) { 
      listStorage.get(position).setSelected(isChecked) 
      notifyDataSetChanged(); 
     } 

    }); 
+0

检查整个项目它的工作原理!非常感谢,我已经搜索了两周以上的网页,但没有找到答案,请您介绍如何在onCheckedChangedListener中进行此操作? – Dragon957

+0

但是,当我尝试发生问题时,我向下滚动列表视图并单击下面的复选框 – Dragon957

+0

您遇到什么问题? –