Android Open Source - android_rss_reader Main Activity






From Project

Back to project page android_rss_reader.

License

The source code is released under:

Apache License

If you think the Android project android_rss_reader 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

/***********************************************************************************************************************
 * ==========================================
 */* w w  w. j ava  2s . co m*/
 * Copyright (C) 2013 by Paul Oremland
 * http://www.linkedin.com/in/pauloremland
 * https://github.com/poremland
 *
 ***********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 ***********************************************************************************************************************/
package net.oremland.rss.reader;

import android.os.*;
import android.support.v4.app.*;
import android.support.v7.app.*;
import android.text.*;
import android.view.*;
import android.widget.*;

import java.util.*;

import net.oremland.rss.reader.fragments.*;
import net.oremland.rss.reader.helpers.*;
import net.oremland.rss.reader.models.*;

public class MainActivity
  extends
    ActionBarActivity
  implements
    AddFeedFragment.OnFeedListChangedListener,
    FeedsListFragment.OnFeedSelectedListener,
    FeedItemsListFragment.OnFeedItemSelectedListener
{
  private int optionsMenuId = this.getDefaultOptionsMenuId();

  protected interface FragmentLifecycleHelper<T extends Fragment>
  {
    T create(int id);
    void update(T fragment);
    void addToFragmentTransaction(FragmentTransaction transaction);
    boolean shouldIncludeMainMenuItems();
  }

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    if(savedInstanceState == null)
    {
      this.showDefaultFragment();
    }
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {
    MenuInflater minflater = getMenuInflater();
    minflater.inflate(this.optionsMenuId, menu);

    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item)
  {
    return this.handledHome(item)
      || this.handledAdd(item)
      || super.onOptionsItemSelected(item);
  }

  private boolean handledHome(MenuItem item)
  {
    if (item.getItemId() == android.R.id.home)
    {
      this.popBackStack();
      return true;
    }
    return false;
  }

  private boolean handledAdd(MenuItem item)
  {
    if (item.getItemId() == R.id.menu_add)
    {
      this.displayAddFeedFragment();
      return true;
    }
    return false;
  }

  @Override
  public void onResume()
  {
    super.onResume();

    this.updateHomeButton();
  }

  @Override
  public void onBackPressed()
  {
    if(!this.popBackStack())
    {
      this.finish();
    }
  }

  @Override
  public void onSaveInstanceState(Bundle outState)
  {
    super.onSaveInstanceState(outState);

    outState.putInt("optionsMenuId", this.optionsMenuId);
  }

  @Override
  public void onRestoreInstanceState(Bundle savedInstanceState)
  {
    super.onRestoreInstanceState(savedInstanceState);

    this.optionsMenuId = savedInstanceState.getInt("optionsMenuId", this.getDefaultOptionsMenuId());
    this.restoreFragmentInstanceState();
  }

  private void restoreFragmentInstanceState()
  {
    Fragment addFeedFragment = this.getFragment(R.id.add_feed_fragment);
    Fragment browserFragment = this.getFragment(R.id.browser_fragment);
    int id = addFeedFragment == null ?
        browserFragment == null ? -1 : R.id.browser_fragment
        : R.id.add_feed_fragment;
    FragmentManager manager = getSupportFragmentManager();
    if(id != -1 && manager != null)
    {
      FragmentTransaction transaction = manager.beginTransaction();
      this.hideFragmentInLayout(R.id.feeds_list_fragment, transaction);
      this.hideFragmentInLayout(R.id.feed_items_list_fragment, transaction);
      transaction.commit();
    }
  }

  @Override
  public void onFeedListChanged()
  {
    Fragment fragment = this.getFragment(R.id.feeds_list_fragment);
    if(fragment != null)
    {
      ((FeedsListFragment)fragment).load();
    }
  }

  @Override
  public void onFeedSelected(Feed feed)
  {
    this.displayFeedItemsListFragment(feed);
  }

  @Override
  public void onFeedItemSelected(FeedItem item)
  {
    this.displayBrowserFragment(item);
  }

  private void showDefaultFragment()
  {
    this.displayFeedsListFragment();
    if(this.shouldDisplayAddFeedFragment())
    {
      this.displayAddFeedFragment();
    }
  }

  private boolean shouldDisplayAddFeedFragment()
  {
    FeedHelper helper = new FeedHelper();
    return helper.getFeeds().size() == 0;
  }

  private void displayAddFeedFragment()
  {
    this.displayFragment(R.id.add_feed_fragment, new FragmentLifecycleHelper<AddFeedFragment>()
    {
      public void addToFragmentTransaction(FragmentTransaction transaction)
      {
        hideFragmentInLayout(R.id.feeds_list_fragment, transaction);
        hideFragmentInLayout(R.id.feed_items_list_fragment, transaction);
      }

      public AddFeedFragment create(int id)
      {
        return new AddFeedFragment();
      }

      public boolean shouldIncludeMainMenuItems()
      {
        return false;
      }

      public void update(AddFeedFragment fragment)
      {
      }
    });
  }

  private void displayFeedsListFragment()
  {
    this.displayFragment(R.id.feeds_list_fragment, new FragmentLifecycleHelper<FeedsListFragment>()
    {
      public void addToFragmentTransaction(FragmentTransaction transaction)
      {
      }

      public FeedsListFragment create(int id)
      {
        FeedsListFragment fragment = new FeedsListFragment();
        return fragment;
      }

      public boolean shouldIncludeMainMenuItems()
      {
        return true;
      }

      public void update(FeedsListFragment fragment)
      {
      }
    });
  }

  private void displayFeedItemsListFragment(final Feed feed)
  {
    this.displayFragment(R.id.feed_items_list_fragment, new FragmentLifecycleHelper<FeedItemsListFragment>()
    {
      public void addToFragmentTransaction(FragmentTransaction transaction)
      {
      }

      public FeedItemsListFragment create(int id)
      {
        FeedItemsListFragment fragment = new FeedItemsListFragment();
        fragment.setFeed(feed);
        return fragment;
      }

      public boolean shouldIncludeMainMenuItems()
      {
        return true;
      }

      public void update(FeedItemsListFragment fragment)
      {
        fragment.setFeed(feed);
        fragment.load();
        LinearLayout.LayoutParams parameters = (LinearLayout.LayoutParams)fragment.getView().getLayoutParams();
        parameters.weight = 2f;
        fragment.getView().setLayoutParams(parameters);
      }
    });
  }

  private void displayBrowserFragment(final FeedItem item)
  {
    this.displayFragment(R.id.browser_fragment, new FragmentLifecycleHelper<BrowserFragment>()
    {
      public void addToFragmentTransaction(FragmentTransaction transaction)
      {
        hideFragmentInLayout(R.id.feeds_list_fragment, transaction);
        hideFragmentInLayout(R.id.feed_items_list_fragment, transaction);
      }

      public BrowserFragment create(int id)
      {
        BrowserFragment fragment = new BrowserFragment();
        fragment.setFeedItem(item);
        return fragment;
      }

      public boolean shouldIncludeMainMenuItems()
      {
        return false;
      }

      public void update(BrowserFragment fragment)
      {
        fragment.setFeedItem(item);
        fragment.loadFeed();
      }
    });
  }

  private void hideFragmentInLayout(int id, FragmentTransaction transaction)
  {
    Fragment fragment = this.getFragment(id);
    if(fragment != null && transaction != null && fragment.isInLayout())
    {
      transaction.hide(fragment);
    }
  }

  protected FeedsListFragment.OnFeedSelectedListener getOnFeedSelectedListener()
  {
    return this;
  }

  protected FeedItemsListFragment.OnFeedItemSelectedListener getOnFeedItemSelectedListener()
  {
    return this;
  }

  private void displayFragment(int id, FragmentLifecycleHelper helper)
  {
    Fragment fragment = this.createOrUpdateFragment(id, helper);
    this.addFragmentToBackStack(fragment, id, helper);
    this.updateHomeButton(id);
    this.optionsMenuId = helper.shouldIncludeMainMenuItems() ? getDefaultOptionsMenuId() : R.menu.empty_menu;
    this.invalidateOptionsMenu();
  }

  private Fragment createOrUpdateFragment(int id, FragmentLifecycleHelper helper)
  {
    Fragment fragment = this.getFragment(id);
    if(fragment == null)
    {
      return helper.create(id);
    }
    helper.update(fragment);
    return fragment;
  }

  private Fragment getFragment(int id)
  {
    FragmentManager manager = getSupportFragmentManager();
    Fragment fragment = manager.findFragmentByTag(this.getFragmentIdAsString(id));
    if(fragment == null)
    {
      fragment = manager.findFragmentById(id);
    }
    return fragment;
  }

  protected void addFragmentToBackStack(Fragment fragment, int id, FragmentLifecycleHelper helper)
  {
    FragmentManager manager = getSupportFragmentManager();
    if(fragment != null && manager != null && !fragment.isInLayout())
    {
      FragmentTransaction transaction = manager.beginTransaction();
      transaction.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK);
      // alternatively you can have more control over the fragment
      // lifecycle by choosing to hide/show fragments by calling
      // transaction.add instead of replace. Calling replace forces
      // each fragment through it's lifecycle.
      helper.addToFragmentTransaction(transaction);
      transaction.replace(R.id.fragment_container, fragment, this.getFragmentIdAsString(id));
      transaction.addToBackStack(this.getFragmentIdAsString(id));
      transaction.commit();
    }
  }

  private String getFragmentIdAsString(int id)
  {
    return Integer.toString(id);
  }

  private boolean popBackStack()
  {
    boolean wasBackStackPopped = false;
    FragmentManager manager = getSupportFragmentManager();
    if(manager != null)
    {
      if(this.shouldPopBackStack(manager))
      {
        this.popBackStack(manager);
        wasBackStackPopped = true;
      }
      this.optionsMenuId = this.getDefaultOptionsMenuId();
      this.invalidateOptionsMenu();
    }
    int id = this.idForPreviousBackStackEntry(manager);
    this.updateHomeButton(id);
    return wasBackStackPopped;
  }

  private boolean shouldPopBackStack(FragmentManager manager)
  {
    return manager.getBackStackEntryCount() > this.initialBackStackCount();
  }

  private int initialBackStackCount()
  {
    boolean isTablet = this.getResources().getBoolean(R.bool.isTablet);
    return isTablet ? 0 : 1;
  }

  private int idForPreviousBackStackEntry(FragmentManager manager)
  {
    int entryCount = manager.getBackStackEntryCount();
    int initialCount = this.initialBackStackCount();
    if(entryCount > initialCount)
    {
      FragmentManager.BackStackEntry entry = manager.getBackStackEntryAt(entryCount - initialCount);
      return Integer.parseInt(entry.getName());
    }
    return R.id.feeds_list_fragment;
  }

  public void invalidateOptionsMenu()
  {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    {
      super.invalidateOptionsMenu();
    }
  }

  private int getDefaultOptionsMenuId()
  {
    return R.menu.main_menu;
  }

  private void popBackStack(FragmentManager manager)
  {
    try
    {
      manager.popBackStackImmediate();
    }
    catch(Exception e)
    {
      // TODO: set flag to pop on resume?
      e.printStackTrace();
    }
  }

  private void updateHomeButton()
  {
    FragmentManager manager = getSupportFragmentManager();
    if(manager != null)
    {
      int id = this.fragmentIdFromBackStackEntry(manager);
      this.updateHomeButton(id);
    }
  }

  private int fragmentIdFromBackStackEntry(FragmentManager manager)
  {
    int backStackEntryCount = manager.getBackStackEntryCount();
    if(backStackEntryCount > 0)
    {
      String name = manager.getBackStackEntryAt(backStackEntryCount - 1).getName();
      if(!TextUtils.isEmpty(name))
      {
        return Integer.parseInt(name);
      }
    }
    return R.id.feeds_list_fragment;
  }

  private void updateHomeButton(int id)
  {
    FragmentManager manager = getSupportFragmentManager();
    if(manager != null)
    {
      String name = this.getFragmentIdAsString(id);
      boolean isTablet = this.getResources().getBoolean(R.bool.isTablet);
      boolean isOnFeedsList = name.equals(this.getFragmentIdAsString(R.id.feeds_list_fragment));
      boolean isNotTabletAndNotOnFirstFragment = !isTablet && !isOnFeedsList;
      boolean isInLayout = this.getFragment(id) != null && this.getFragment(id).isInLayout();
      boolean isTabletAndOnFragmentNotInLayout = isTablet && !isInLayout;
      this.updateHomeButton(isNotTabletAndNotOnFirstFragment || isTabletAndOnFragmentNotInLayout);
    }
  }

  private void updateHomeButton(boolean enableHomeButton)
  {
    getSupportActionBar().setDisplayHomeAsUpEnabled(enableHomeButton);
    getSupportActionBar().setHomeButtonEnabled(enableHomeButton);
  }
}




Java Source Code List

net.oremland.rss.reader.MainActivity.java
net.oremland.rss.reader.MainApplication.java
net.oremland.rss.reader.fragments.AddFeedFragment.java
net.oremland.rss.reader.fragments.BaseAdapter.java
net.oremland.rss.reader.fragments.BaseListFragment.java
net.oremland.rss.reader.fragments.BrowserFragment.java
net.oremland.rss.reader.fragments.FeedItemsAdapter.java
net.oremland.rss.reader.fragments.FeedItemsListFragment.java
net.oremland.rss.reader.fragments.FeedsAdapter.java
net.oremland.rss.reader.fragments.FeedsListFragment.java
net.oremland.rss.reader.helpers.AsyncHttpDownloader.java
net.oremland.rss.reader.helpers.FeedHelper.java
net.oremland.rss.reader.helpers.FeedItemCache.java
net.oremland.rss.reader.helpers.FeedItemHelper.java
net.oremland.rss.reader.helpers.FeedParser.java
net.oremland.rss.reader.helpers.ObjectSerializer.java
net.oremland.rss.reader.models.BaseModel.java
net.oremland.rss.reader.models.FeedItem.java
net.oremland.rss.reader.models.Feed.java