2017-03-10 85 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

您遇到什麼問題? –