2017-03-10 4 views
0

Ich versuche gerade einen einfachen Task Killer zu Lernzwecken zu erstellen, ich erstellte eine Listenansicht, die alle vom Benutzer installierten Apps mit Checkbox anzeigt, damit der Benutzer mit Apps auswählen konnte, wenn der Bildschirm ausgeschaltet war.Speicherstatus der dynamisch erstellten Checkbox

Aber ich stecke, wie das Kontrollkästchen Zustand speichern und die aufgegebenen App Paketnamen

Ich habe Such Stack-Überlauf eine lange Zeit zu erhalten, aber noch nicht wissen, wie es zu tun, bitte helfen Sie mir, Dank

Dies ist mein Code

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; 
} 
} 

Vielen Dank im Voraus

Antwort

1

Schnittstelle erstellen:

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

Fügen Sie es zu Ihrem 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; 
    } 

    .... 
} 

Implementieren in indem Sie Ihre 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); 
    } 

    .... 
} 

Ihre AppList-Klasse sollte keine Verweise auf Context oder SharedPreferences und Logik zum "Überprüfen"/"Abwählen" enthalten. Es sollte einfach POJO sein.

Schnittstelle verwenden Sie können leicht geteilt Präferenzen ersetzen mit einer anderen Art von Repository wie SQLite

EDITED: Ich AppAdapter getView mwthod ändern:

  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()); 
       } 
      } 
     }); 

Sie vollen Projekt überprüfen können https://github.com/valeragit/AppListExample

+0

Ich habe versucht Ihren Code, aber nicht arbeiten, speichern sie das Kontrollkästchen noch nicht Zustand – Dragon957

+0

Edited, obwohl Testprojekt hinzufügen –

+0

ich versuche, das Projekt und testen sie die App zu importieren, aber es immer noch nicht funktioniert, nachdem die Listenansicht das Kontrollkästchen Scrollen nach einigen Recherchen nicht markiert wurde wieder – Dragon957

1

Sie rief nie AppList.setSelected(). Rufen Sie als auf ListViewHolder OnClickListener und dann wahrscheinlich den Adapter benachrichtigen, dass es Änderungen gibt. Sie auch wollen wahrscheinlich setChecked nennen, anstatt 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(); 
      } 
     }); 

Sie können dies weiter verbessern, indem ein checkChangedListener eher als ein OnClickListener Einstellung, aber zuerst das Ausgangsproblem lösen.

Edit: OP Das erste Problem gelöst, jetzt für Verbesserungen kommentieren. Ersetzen diese onClick mit:

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

    }); 
+0

Es funktioniert !!! Vielen Dank, ich habe über zwei Wochen im Internet gesucht, aber keine Antwort gefunden. Kannst du bitte zeigen, wie man dies in onCheckedChangedListener macht? – Dragon957

+0

Aber nachdem ich die Probleme versuchen, treten auf, wenn ich die Listenansicht nach unten scrollen und klicken Sie auf das Kontrollkästchen unter – Dragon957

+0

Welche Probleme treten? –

Verwandte Themen