Android滑动菜单 - 用户名和图像。如何永久加载它们

时间:2013-12-03 19:03:56

标签: java android slidingmenu

我的Android应用中有一个滑动菜单和一个操作栏。 在滑动菜单的顶部有一个用户名和一个用户图片 如果我将它们设置一次,当我关闭并再次打开菜单时它们会丢失。

因此,每当它打开我调用用户详细信息下载器类并且我再次设置名称和头像时,这是非常恼人的。

如果关闭应用程序,无论是打开还是关闭滑动菜单,我怎样才能设置它们并且不要打扰它?

public class AsdActionBarAndSlidingMenu extends AsdActionBar implements IOnUserDetailsAndStatsReceivedListener{ 
    private TextView tvSlidingMenuUserName;
    private Typeface font2;
    private UserDetailsAndStatsDownloader mUserDetailsDownloader;
    private String userName;
    private ImageView ivSlidingMenuUserAvatar;
    private String avatarPath;
    private Bitmap ivSlidingMenuUserBitmap;
    private static final String APP_SHARED_PREFS = "asdasd_prefs";
    SharedPreferences sharedPrefs;
    public Editor editor;
    protected int currentlyLoggedInUser;
    protected String currentlyLoggedInUserString;

    public AsdActionBarAndSlidingMenu(int titleRes) {
        super(R.string.app_name);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setBehindContentView(R.layout.menu_frame);
        sharedPrefs = getApplicationContext().getSharedPreferences(APP_SHARED_PREFS, Context.MODE_PRIVATE);

        currentlyLoggedInUser = sharedPrefs.getInt("currentLoggedInUserId", 0);
        currentlyLoggedInUserString = Integer.toString(currentlyLoggedInUser);



        tvSlidingMenuUserName = (TextView) findViewById(R.id.tvSlidingMenuUserName);
        tvSlidingMenuUserName.setTypeface(font2);

        getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.menu_frame, new AsdSlidingMenuListFragment()).commit();   
        getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        setSlidingActionBarEnabled(true);

        getSlidingMenu().setOnOpenedListener(new OnOpenedListener() {

            @Override
            public void onOpened() {

                mUserDetailsDownloader = new UserDetailsAndStatsDownloader(currentlyLoggedInUserString, AsdActionBarAndSlidingMenu.this, AsdActionBarAndSlidingMenu.this);
                mUserDetailsDownloader.downloadUserDetailsAndStats();

            }
        });
    }
    @Override
    public void onUserDetailsAndStatsReceivedListener(UserDetailsAndStats userDetailsAndStats) {
        userName = userDetailsAndStats.getUserName();
        tvSlidingMenuUserName = (TextView) findViewById(R.id.tvSlidingMenuUserName);
        tvSlidingMenuUserName.setText(userName);

        avatarPath = userDetailsAndStats.getUserAvatar();
        ivSlidingMenuUserBitmap = BitmapFactory.decodeFile(avatarPath);
        ivSlidingMenuUserAvatar = (ImageView) findViewById(R.id.ivSlidingMenuUserAvatar);
        ivSlidingMenuUserAvatar.setImageBitmap(ivSlidingMenuUserBitmap);

    }

}

2 个答案:

答案 0 :(得分:1)

但是,未设置的是BitMap,或ViewsivSlidingMenuUserAvatartvSlidingMenuUserName)?

我不知道你是如何创建的UserDetailsAndStatsDownloader,但可能在不同的线程中调用了onUserDetailsAndStatsReceivedListener。这可能会导致当该线程未运行且这些视图未使用时,您可能会丢失它们。但我不确定。

无论如何,尝试在onCreate中夸大你的观点,并在此之后检索数据

public void onCreate(Bundle savedInstanceState) {  
   ...
   tvSlidingMenuUserName = (TextView) findViewById(R.id.tvSlidingMenuUserName);
   ivSlidingMenuUserAvatar = (ImageView) findViewById(R.id.ivSlidingMenuUserAvatar);
  mUserDetailsDownloader = new UserDetailsAndStatsDownloader(currentlyLoggedInUserString, AsdActionBarAndSlidingMenu.this, AsdActionBarAndSlidingMenu.this);
                mUserDetailsDownloader.downloadUserDetailsAndStats();   
}

让听众就像这样

@Override
public void onUserDetailsAndStatsReceivedListener(UserDetailsAndStats userDetailsAndStats){
    userName = userDetailsAndStats.getUserName();
    tvSlidingMenuUserName.setText(userName);
    avatarPath = userDetailsAndStats.getUserAvatar();
    ivSlidingMenuUserBitmap = BitmapFactory.decodeFile(avatarPath);
    ivSlidingMenuUserAvatar.setImageBitmap(ivSlidingMenuUserBitmap);
}

然后,删除getSlidingMenu().setOnOpenedListener(...)并让我们看看发生了什么。

此外,您应该使用任何缓存方法进行下载,因此即使您需要再次下载文件,如果您已经完成,也不会涉及网络操作。例如,您可以像android-imagedownloader中所示这样做,这是一个非常简单的示例。

 /*
     * Cache-related fields and methods.
     * 
     * We use a hard and a soft cache. A soft reference cache is too aggressively cleared by the
     * Garbage Collector.
     */

    private static final int HARD_CACHE_CAPACITY = 10;
    private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds

    // Hard cache, with a fixed maximum capacity and a life duration
    private final HashMap<String, Bitmap> sHardBitmapCache =
        new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
            if (size() > HARD_CACHE_CAPACITY) {
                // Entries push-out of hard reference cache are transferred to soft reference cache
                sSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));
                return true;
            } else
                return false;
        }
    };

    // Soft cache for bitmaps kicked out of hard cache
    private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache =
        new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);

    private final Handler purgeHandler = new Handler();

    private final Runnable purger = new Runnable() {
        public void run() {
            clearCache();
        }
    };

    /**
     * Adds this bitmap to the cache.
     * @param bitmap The newly downloaded bitmap.
     */
    private void addBitmapToCache(String url, Bitmap bitmap) {
        if (bitmap != null) {
            synchronized (sHardBitmapCache) {
                sHardBitmapCache.put(url, bitmap);
            }
        }
    }

    /**
     * @param url The URL of the image that will be retrieved from the cache.
     * @return The cached bitmap or null if it was not found.
     */
    private Bitmap getBitmapFromCache(String url) {
        // First try the hard reference cache
        synchronized (sHardBitmapCache) {
            final Bitmap bitmap = sHardBitmapCache.get(url);
            if (bitmap != null) {
                // Bitmap found in hard cache
                // Move element to first position, so that it is removed last
                sHardBitmapCache.remove(url);
                sHardBitmapCache.put(url, bitmap);
                return bitmap;
            }
        }

        // Then try the soft reference cache
        SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(url);
        if (bitmapReference != null) {
            final Bitmap bitmap = bitmapReference.get();
            if (bitmap != null) {
                // Bitmap found in soft cache
                return bitmap;
            } else {
                // Soft reference has been Garbage Collected
                sSoftBitmapCache.remove(url);
            }
        }

        return null;
    }

    /**
     * Clears the image cache used internally to improve performance. Note that for memory
     * efficiency reasons, the cache will automatically be cleared after a certain inactivity delay.
     */
    public void clearCache() {
        sHardBitmapCache.clear();
        sSoftBitmapCache.clear();
    }

如果我们有所涉及的其他类的代码(只是您所写的那些代码),那么帮助可能会更准确。

答案 1 :(得分:0)

这行代码负责从avatarPath加载位图,对吗?

ivSlidingMenuUserBitmap = BitmapFactory.decodeFile(avatarPath);

如果你想永远这样做,你应该只进行一次解码并将其值存储在代码的其他地方。您已经将值存储在字段中,因此您不需要继续从文件中解码它。

在该行之前添加简单的if (ivSlidingMenuUserBitmap != null)应该可以防止这种情况发生。像这样:

avatarPath = userDetailsAndStats.getUserAvatar();
if (ivSlidingMenuUserBitmap != null)
    ivSlidingMenuUserBitmap = BitmapFactory.decodeFile(avatarPath);
ivSlidingMenuUserAvatar = (ImageView) findViewById(R.id.ivSlidingMenuUserAvatar);
ivSlidingMenuUserAvatar.setImageBitmap(ivSlidingMenuUserBitmap);