Android Open Source - android-autostarts My Expandable List Adapter






From Project

Back to project page android-autostarts.

License

The source code is released under:

GNU General Public License

If you think the Android project android-autostarts listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 *//from   w  ww.j  ava2 s .  co m
 */
package com.elsdoerfer.android.autostarts;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.SpannableStringBuilder;
import android.text.style.StrikethroughSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.elsdoerfer.android.autostarts.db.ComponentInfo;
import com.elsdoerfer.android.autostarts.db.IntentFilterInfo;
import com.elsdoerfer.android.autostarts.db.PackageInfo;

import static com.elsdoerfer.android.autostarts.Utils.containsIgnoreCase;


/**
 * ListAdapter used by the ListActivity. Has it's own top-level file to
 * keep file sizes small.
 */
public class MyExpandableListAdapter extends BaseExpandableListAdapter {

  static final public int GROUP_BY_ACTION = 1;
  static final public int GROUP_BY_PACKAGE = 2;

  private ListActivity mActivity;
  private ArrayList<IntentFilterInfo> mDataAll;
  private GroupingImpl mGroupDisplay;
  private int mCurrentGrouping = GROUP_BY_ACTION;

  private boolean mHideSystemApps = false;
  private boolean mHideUnknownEvents = false;
  private boolean mShowChangedOnly = false;
  private String mTextFilter = "";

  private LayoutInflater mInflater;

  public MyExpandableListAdapter(ListActivity activity) {
    mActivity = activity;
    mInflater = (LayoutInflater) activity.getSystemService(
        Context.LAYOUT_INFLATER_SERVICE);
    setData(new ArrayList<IntentFilterInfo>());
  }

  public void setData(ArrayList<IntentFilterInfo> data) {
    mDataAll = data;
    rebuildGroupDisplay();
  }

  public void setGrouping(int groupMode) {
    if (mCurrentGrouping != groupMode) {
      mCurrentGrouping = groupMode;
      rebuildGroupDisplay();
    }
  }

  public int getGrouping() {
    return mCurrentGrouping;
  }

  private boolean checkAgainstFilters(IntentFilterInfo info) {
    ComponentInfo comp = info.componentInfo;

    // If a text filter is active, all other filters are ignored
    if (!mTextFilter.equals("")) {
      if (containsIgnoreCase(comp.componentLabel, mTextFilter))
        return true;
      if (containsIgnoreCase(comp.componentName, mTextFilter))
        return true;
      if (containsIgnoreCase(comp.packageInfo.packageLabel, mTextFilter))
        return true;
      if (containsIgnoreCase(comp.packageInfo.packageName, mTextFilter))
      return true;
      // Search comp.intentFilters too?
      return false;
    }

    if (mHideSystemApps && comp.packageInfo.isSystem)
      return false;
    if (mShowChangedOnly && comp.isCurrentlyEnabled() ==
          comp.defaultEnabled)
      return false;
    if (mHideUnknownEvents && Utils.getHashMapIndex
        (Actions.MAP, info.action) == -1)
      return false;
    return true;
  };

  /**
   * Rebuild the grouping-mode specific rendering object. This
   * re-applies the filters.
   *
   * TODO: Add a way to init all filters (setFilterFOO calls) without
   * updating the data once for every filter option. Simplest way:
   * generate this on demand?
   */
  private void rebuildGroupDisplay() {
    switch (mCurrentGrouping) {
    case GROUP_BY_ACTION:
      mGroupDisplay = new GroupByActionImpl(mDataAll, this);
      break;
    case GROUP_BY_PACKAGE:
      mGroupDisplay = new GroupByPackageImpl(mDataAll, this);
    }
  }

  public Object getChild(int groupPosition, int childPosition) {
    return mGroupDisplay.getChild(groupPosition, childPosition);
  }

  public long getChildId(int groupPosition, int childPosition) {
    return mGroupDisplay.getChildId(groupPosition, childPosition);
  }

  public int getChildrenCount(int groupPosition) {
    return mGroupDisplay.getChildrenCount(groupPosition);
  }

  public View getChildView(int groupPosition, int childPosition,
      boolean isLastChild, View convertView, ViewGroup parent) {
    return mGroupDisplay.getChildView(groupPosition, childPosition,
        isLastChild, convertView, parent);
  }

  public Object getGroup(int groupPosition) {
    return mGroupDisplay.getGroup(groupPosition);
  }

  public int getGroupCount() {
    return mGroupDisplay.getGroupCount();
  }

  public long getGroupId(int groupPosition) {
    return mGroupDisplay.getGroupId(groupPosition);
  }

  public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
      ViewGroup parent) {
    return mGroupDisplay.getGroupView(groupPosition, isExpanded,
        convertView, parent);
  }

  public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
  }

  public boolean hasStableIds() {
    return true;
  }

  /**
   * Return true if any filters are active.
   */
  public boolean isFiltered() {

    return mHideSystemApps || mShowChangedOnly || mHideUnknownEvents || !mTextFilter.equals("");
  }

  /**
   * Allow owner to hide (and show) the system applications.
   *
   * Returns True if the list is filtered.
   *
   * Expects the caller to also call notifyDataSetChanged(), if
   * necessary.
   */
  public boolean toggleFilterSystemApps() {
      setFilterSystemApps(!mHideSystemApps);
    return mHideSystemApps;
  }

  /**
   * Manually decide whether to filter out system applications.
   *
   * Expects the caller to also call notifyDataSetChanged(), if
   * necessary.
   */
  public void setFilterSystemApps(boolean newState) {
    if (newState != mHideSystemApps) {
      mHideSystemApps = newState;
      rebuildGroupDisplay();
    }
  }

  public boolean getFilterSystemApps() {
    return mHideSystemApps;
  }

  public void setShowChangedOnly(boolean newState) {
    if (newState != mShowChangedOnly) {
      mShowChangedOnly = newState;
      rebuildGroupDisplay();
    }
  }

  public boolean getShowChangedOnly() {
    return mShowChangedOnly;
  }

  public void setFilterUnknown(boolean newState) {
    if (newState != mHideUnknownEvents) {
      mHideUnknownEvents = newState;
      rebuildGroupDisplay();
    }
  }

  public boolean getFilterUnknown() {
    return mHideUnknownEvents;
  }

  public void setTextFilter(String query) {
    if (query != mTextFilter) {
      mTextFilter = query;
      rebuildGroupDisplay();
    }
  }

  public String getTextFilter() {
    return mTextFilter;
  }


  @SuppressWarnings("serial")
  static class MapOfIntents<K> extends HashMap<K, ArrayList<IntentFilterInfo>> {
    /**
     * Simplified put() that will automatically create the list
     * object that is the TreeMap value, and appends to that list.
     */
    public K put(K key, IntentFilterInfo value) {
      if (!this.containsKey(key)) {
        this.put(key, new ArrayList<IntentFilterInfo>());
      }
      this.get(key).add(value);
      return key;
    }
  }

  /**
   * Abstract a "group view". We want to allow our data be be shown
   * in different group modes: group by package, or group by action.
   *
   * Rather than using two ExpandableListAdapter implementations
   * (where we would have to keep the applied filter options etc. in
   * sync), we instead use a single adapter and abstracting out the
   * code that is specific to a grouping mode.
   *
   */
  static private abstract class GroupingImpl
  {
    public abstract int getGroupCount();
    public abstract Object getGroup(int groupPosition);
    public abstract long getGroupId(int groupPosition);
    public abstract View getGroupView(int groupPosition,
        boolean isExpanded, View convertView, ViewGroup parent);
    public abstract int getChildrenCount(int groupPosition);
    public abstract View getChildView(int groupPosition,
        int childPosition, boolean isLastChild, View convertView,
        ViewGroup parent);
    public abstract long getChildId(int groupPosition, int childPosition);
    public abstract Object getChild(int groupPosition, int childPosition);

    protected MyExpandableListAdapter mParent;

    GroupingImpl(MyExpandableListAdapter parent) {
      mParent = parent;
    }

    /**
     * Helper for child classes to return a view for a list item.
     *
     * If "existing" has a tag that matches "tag", it will be
     * re-used (this is necessary due to different grouping modes
     * using different layouts). Otherwise, a new view is created
     * based on "layout", as a child of "parent".
     */
    protected View getView(View existing, String tag, int layout,
        ViewGroup parent) {
      if (existing == null || (String)existing.getTag() != "tag")
        return mParent.mInflater.inflate(layout, parent, false);
      else
        return existing;
    }

    /**
     * Helper for child classes to initialize a "show info" button
     * that would display information about am event.
     */
    protected void setActionInfo(View root, final String action) {
      View v = root.findViewById(R.id.show_info);
      if (!Actions.MAP.containsKey(action))
        v.setVisibility(View.GONE);
      else {
        v.setOnClickListener(new OnClickListener() {
          public void onClick(View _v) {
            mParent.mActivity.showInfoToast(action);
          }
        });
      }
    }

    /**
     * Helper to set the text style for a list item based on
     * whether it represents a system app, something that disabled
     * etc.
     *
     * Arguments can be null.
     */
    protected void setTextStyle(TextView t, PackageInfo pkg,
        ComponentInfo comp) {
      if (pkg!= null && pkg.isSystem)
        t.setTextColor(Color.YELLOW);
      else
        t.setTextColor(mParent.mActivity.getResources().getColor(
            android.R.color.primary_text_dark));

      if (comp != null && comp.isCurrentlyEnabled() != comp.defaultEnabled)
        t.setTypeface(Typeface.DEFAULT_BOLD);
      else
        t.setTypeface(Typeface.DEFAULT);
    }

    /**
     * Helper for child classes to set the text of an item that
     * represents a component. This adds the component label to "base"
     * in the rare case one exists, and also makes sure to strike
     * the text if the component is disabled.
     */
    protected void setComponentText(TextView t, ComponentInfo comp,
        String base) {
      SpannableStringBuilder fullText = new SpannableStringBuilder();
      fullText.append(base);
      if (comp.componentLabel != null && !comp.componentLabel.equals(""))
        fullText.append(" ("+comp.componentLabel+")");
      if (!comp.isCurrentlyEnabled())
        fullText.setSpan(new StrikethroughSpan(), 0, fullText.length(), 0);
      t.setText(fullText);
    }
  }

  /**
   * Group by Action.
   */
  static private class GroupByActionImpl extends GroupingImpl {

    ArrayList<String> mGroups;
    MapOfIntents<String> mChildren;

    GroupByActionImpl(ArrayList<IntentFilterInfo> data,
        MyExpandableListAdapter adapter) {
      super(adapter);

      mGroups = new ArrayList<String>();
      mChildren = new MapOfIntents<String>();

      for (IntentFilterInfo info : data)
      {
        if (adapter.checkAgainstFilters(info))
        {
          if (!mGroups.contains(info.action))
            mGroups.add(info.action);
          mChildren.put(info.action, info);
        }
      }

      // Sort by order of actions in our known action database.
      Collections.sort(mGroups, new Comparator<String>() {
        public int compare(String action1, String action2) {
          return Actions.compare(action1, action2);
        }
      });
      // Sort children by descending priority
      for (ArrayList<IntentFilterInfo> group : mChildren.values()) {
        Collections.sort(group, new Comparator<IntentFilterInfo>() {
          @Override
          public int compare(IntentFilterInfo object1,
              IntentFilterInfo object2) {
            return -Float.compare(object1.priority, object2.priority);
          }
        });
      }
    }

    public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent)
    {
      String action = (String) getGroup(groupPosition);

      View v = getView(convertView, "act-group",
          R.layout.by_act_group_row, parent);
      setActionInfo(v, action);

      ((TextView)v.findViewById(R.id.title)).setText(
          mParent.mActivity.getIntentName(action));

      return v;
    }

    public View getChildView(int groupPosition, int childPosition,
        boolean isLastChild, View convertView, ViewGroup parent)
    {
      View v = getView(convertView, "act-child",
          R.layout.by_act_child_row, parent);

      IntentFilterInfo info = (IntentFilterInfo) getChild(
          groupPosition, childPosition);
      ComponentInfo comp = info.componentInfo;

      // Set the icon
      ImageView img = ((ImageView)v.findViewById(R.id.icon));
        img.setImageDrawable(comp.packageInfo.icon);

      // Set the text
      TextView title = ((TextView)v.findViewById(R.id.title));
      setTextStyle(title, comp.packageInfo, comp);
      setComponentText(title, comp, comp.getLabel());

      // Hide the spinner by default
      ProgressBar spinner = (ProgressBar)v.findViewById(R.id.spinner);
      ToggleService toggleService = mParent.mActivity.mToggleService;
      if (toggleService != null && toggleService.has(comp))
        spinner.setVisibility(View.VISIBLE);
      else
        spinner.setVisibility(View.GONE);

      return v;
    }

    public int getGroupCount() {
      return mGroups.size();
    }

    @Override
    public Object getGroup(int groupPosition) {
      return mGroups.get(groupPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
      return mGroups.get(groupPosition).hashCode();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
      return mChildren.get(mGroups.get(groupPosition)).size();
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
      return getChild(groupPosition, childPosition).hashCode();
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
      return mChildren.get(mGroups.get(groupPosition)).get(childPosition);
    }
  }

  /**
   * Group events by package.
   */
  static private class GroupByPackageImpl extends GroupingImpl {

    ArrayList<PackageInfo> mGroups;
    MapOfIntents<PackageInfo> mChildren;

    GroupByPackageImpl(ArrayList<IntentFilterInfo> data,
        MyExpandableListAdapter adapter) {
      super(adapter);

      mGroups = new ArrayList<PackageInfo>();
      mChildren = new MapOfIntents<PackageInfo>();

      for (IntentFilterInfo info : data)
      {
        if (adapter.checkAgainstFilters(info))
        {
          if (!mGroups.contains(info.componentInfo.packageInfo))
            mGroups.add(info.componentInfo.packageInfo);
          mChildren.put(info.componentInfo.packageInfo, info);
        }
      }

      // Sort groups alphabetically
      Collections.sort(mGroups, new Comparator<PackageInfo>() {
        @Override
        public int compare(PackageInfo object1, PackageInfo object2) {
          return object1.getLabel().compareToIgnoreCase(object2.getLabel());
        }
      });
      // Sort children by our action ordering.
      for (ArrayList<IntentFilterInfo> group : mChildren.values()) {
        Collections.sort(group, new Comparator<IntentFilterInfo>() {
          @Override
          public int compare(IntentFilterInfo object1,
              IntentFilterInfo object2) {
            return Actions.compare(object1.action, object2.action);
          }
        });
      }
    }

    public int getGroupCount() {
      return mGroups.size();
    }

    public long getGroupId(int groupPosition) {
      return mGroups.get(groupPosition).hashCode();
    }

    public Object getGroup(int groupPosition) {
      return mGroups.get(groupPosition);
    }

    public int getChildrenCount(int groupPosition) {
      return mChildren.get(mGroups.get(groupPosition)).size();
    }

    public long getChildId(int groupPosition, int childPosition) {
      return getChild(groupPosition, childPosition).hashCode();
    }

    public Object getChild(int groupPosition, int childPosition) {
      return mChildren.get(mGroups.get(groupPosition)).get(childPosition);
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent)
    {
      PackageInfo pkg = (PackageInfo)getGroup(groupPosition);
      View v = getView(convertView, "pkg-group",
          R.layout.by_pkg_group_row, parent);

      // Set the icon
      ImageView img = ((ImageView)v.findViewById(R.id.icon));
        img.setImageDrawable(pkg.icon);

        // Set the text (app name)
      TextView textView = (TextView)v.findViewById(R.id.title);
      textView.setText(pkg.getLabel());
      setTextStyle(textView, pkg, null);

      return v;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition,
        boolean isLastChild, View convertView, ViewGroup parent)
    {
      IntentFilterInfo info = (IntentFilterInfo) getChild(
          groupPosition, childPosition);

      View v = getView(convertView, "pkg-child",
          R.layout.by_pkg_child_row, parent);
      setActionInfo(v, info.action);

      TextView text = ((TextView)v.findViewById(R.id.title));
      setTextStyle(text, null, info.componentInfo);
      setComponentText(text, info.componentInfo,
          mParent.mActivity.getIntentName(info.action));

      ImageView infoIcon = ((ImageView)v.findViewById(R.id.show_info));
      ProgressBar spinner = ((ProgressBar)v.findViewById(R.id.spinner));

      ToggleService toggleService = mParent.mActivity.mToggleService;
      if (toggleService != null && toggleService.has(info.componentInfo)) {
        spinner.setVisibility(View.VISIBLE);
        infoIcon.setVisibility(View.GONE);
      }
      else {
        spinner.setVisibility(View.GONE);
        infoIcon.setVisibility(View.VISIBLE);
      }

      return v;
    }
  }

}




Java Source Code List

com.elsdoerfer.android.autostarts.Actions.java
com.elsdoerfer.android.autostarts.DatabaseHelper.java
com.elsdoerfer.android.autostarts.EventDetailsFragment.java
com.elsdoerfer.android.autostarts.HelpActivity.java
com.elsdoerfer.android.autostarts.ListActivity.java
com.elsdoerfer.android.autostarts.LoadTask.java
com.elsdoerfer.android.autostarts.MyExpandableListAdapter.java
com.elsdoerfer.android.autostarts.ReceiverReader.java
com.elsdoerfer.android.autostarts.ToggleService.java
com.elsdoerfer.android.autostarts.ToggleTool.java
com.elsdoerfer.android.autostarts.Utils.java
com.elsdoerfer.android.autostarts.compat.FixedExpandableListView.java
com.elsdoerfer.android.autostarts.db.ComponentInfo.java
com.elsdoerfer.android.autostarts.db.IntentFilterInfo.java
com.elsdoerfer.android.autostarts.db.PackageInfo.java
com.stericson.RootTools.Constants.java
com.stericson.RootTools.RootTools.java
com.stericson.RootTools.containers.Mount.java
com.stericson.RootTools.containers.Permissions.java
com.stericson.RootTools.containers.RootClass.java
com.stericson.RootTools.containers.Symlink.java
com.stericson.RootTools.exceptions.RootDeniedException.java
com.stericson.RootTools.execution.CommandCapture.java
com.stericson.RootTools.execution.Command.java
com.stericson.RootTools.execution.JavaCommandCapture.java
com.stericson.RootTools.execution.Shell.java
com.stericson.RootTools.internal.Installer.java
com.stericson.RootTools.internal.InternalVariables.java
com.stericson.RootTools.internal.Remounter.java
com.stericson.RootTools.internal.RootToolsInternalMethods.java
com.stericson.RootTools.internal.Runner.java
src.com.elsdoerfer.android.autostarts.opt.MarketUtils.java
src.com.elsdoerfer.android.autostarts.opt.MarketUtils.java
src.com.elsdoerfer.android.autostarts.opt.RootFeatures.java
src.com.elsdoerfer.android.autostarts.opt.RootFeatures.java