-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
19 changed files
with
707 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package se.kodsnack; | ||
|
||
import android.content.Context; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.ArrayAdapter; | ||
import android.widget.LinearLayout; | ||
import android.widget.TextView; | ||
|
||
import java.util.List; | ||
|
||
import se.kodsnack.util.Episode; | ||
|
||
/** | ||
* Subclass of {@link android.widget.ArrayAdapter} that holds a list of | ||
* Kodsnack's episodes. | ||
* | ||
* @author Erik Jansson<[email protected]> | ||
*/ | ||
public class EpisodeListAdapter extends ArrayAdapter<Episode> { | ||
private LayoutInflater inflater; | ||
|
||
public EpisodeListAdapter(Context context) { | ||
super(context, R.layout.episode_item); | ||
inflater = LayoutInflater.from(context); | ||
} | ||
|
||
/** | ||
* Replace the data in this adapter. | ||
* | ||
* @param data The new list of episodes. | ||
*/ | ||
public void setData(List<Episode> data) { | ||
clear(); | ||
if (data != null) { | ||
addAll(data); | ||
} | ||
} | ||
|
||
@Override | ||
public View getView(int position, View convertView, ViewGroup parent) { | ||
final LinearLayout view; | ||
final Episode episode; | ||
final ViewHolder viewHolder; | ||
|
||
/* Check if we need to inflate a new view of can recycle and old one. */ | ||
if (convertView == null) { | ||
viewHolder = new ViewHolder(); | ||
view = (LinearLayout) inflater.inflate(R.layout.episode_item, parent, false); | ||
|
||
viewHolder.title = (TextView) view.findViewById(R.id.title); | ||
|
||
view.setTag(viewHolder); | ||
} else { | ||
view = (LinearLayout) convertView; | ||
viewHolder = (ViewHolder) view.getTag(); | ||
} | ||
|
||
episode = getItem(position); | ||
viewHolder.title.setText(episode.name); | ||
|
||
return view; | ||
} | ||
|
||
/** | ||
* Private view holder class that caches the findViewById() result since | ||
* it's expensive to perform view lookups every time a new list element | ||
* is cycled in. | ||
*/ | ||
private class ViewHolder { | ||
private TextView title; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package se.kodsnack; | ||
|
||
import android.app.Activity; | ||
import android.content.ComponentName; | ||
import android.content.Context; | ||
import android.content.Intent; | ||
import android.content.ServiceConnection; | ||
import android.os.Bundle; | ||
import android.os.IBinder; | ||
import android.support.v4.app.ListFragment; | ||
import android.support.v4.app.LoaderManager; | ||
import android.support.v4.content.Loader; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.ListView; | ||
|
||
import java.util.List; | ||
|
||
import se.kodsnack.util.Episode; | ||
|
||
/** | ||
* Subclass of {@link android.support.v4.app.ListFragment} that | ||
* displays {@link Episode}s from Kodsnack's Atom feed. | ||
* | ||
* @author Erik Jansson<[email protected]> | ||
*/ | ||
public class EpisodeListFragment extends ListFragment | ||
implements LoaderManager.LoaderCallbacks<List<Episode>> { | ||
private EpisodeListAdapter episodeAdapter; // List adapter that holds the data. | ||
private PlayerService playerService; // The service playing the stream. | ||
|
||
/** | ||
* The connection to the PlayerService. | ||
*/ | ||
private final ServiceConnection playerConnection = new ServiceConnection() { | ||
public void onServiceConnected(ComponentName className, IBinder service) { | ||
playerService = ((PlayerService.LocalBinder) service).getService(); | ||
} | ||
|
||
public void onServiceDisconnected(ComponentName className) { | ||
playerService = null; | ||
} | ||
}; | ||
|
||
@Override | ||
public void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
|
||
episodeAdapter = new EpisodeListAdapter(getActivity()); | ||
setListAdapter(episodeAdapter); | ||
} | ||
|
||
@Override | ||
public View onCreateView(LayoutInflater inflater, ViewGroup container, | ||
Bundle savedInstanceState) { | ||
return inflater.inflate(R.layout.fragment_episode_list, container, false); | ||
} | ||
|
||
@Override | ||
public void onListItemClick(ListView l, View v, int position, long id) { | ||
final Episode episode = episodeAdapter.getItem(position); | ||
playerService.prepareMedia(episode.url); | ||
} | ||
|
||
@Override | ||
public void onAttach(Activity activity) { | ||
super.onAttach(activity); | ||
// Start PlayerService ... | ||
final Intent i = new Intent(activity, PlayerService.class); | ||
activity.startService(i); | ||
// ... and bind to it. | ||
activity.bindService(i, playerConnection, Context.BIND_AUTO_CREATE); | ||
} | ||
|
||
@Override | ||
public void onStart() { | ||
super.onStart(); | ||
getLoaderManager().initLoader(0, null, this); | ||
} | ||
|
||
@Override | ||
public void onDestroy() { | ||
super.onDestroy(); | ||
if (playerService != null) { | ||
getActivity().unbindService(playerConnection); | ||
playerService = null; | ||
} | ||
} | ||
|
||
/** | ||
* Returns the title of this fragment. | ||
* | ||
* @return The title of this fragment. | ||
*/ | ||
public String getTitle() { | ||
return "Avsnitt"; | ||
} | ||
|
||
@Override | ||
public Loader<List<Episode>> onCreateLoader(int id, Bundle args) { | ||
return new EpisodeLoader(getActivity()); | ||
} | ||
|
||
@Override | ||
public void onLoadFinished(Loader<List<Episode>> loader, List<Episode> data) { | ||
episodeAdapter.setData(data); | ||
episodeAdapter.notifyDataSetChanged(); | ||
} | ||
|
||
@Override | ||
public void onLoaderReset(Loader<List<Episode>> loader) { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package se.kodsnack; | ||
|
||
import android.support.v4.content.AsyncTaskLoader; | ||
import android.content.Context; | ||
import android.util.Log; | ||
|
||
import org.xmlpull.v1.XmlPullParserException; | ||
|
||
import java.io.IOException; | ||
import java.text.ParseException; | ||
import java.util.List; | ||
|
||
import se.kodsnack.util.AtomParser; | ||
import se.kodsnack.util.Episode; | ||
|
||
/** | ||
* Subclass of {@link android.support.v4.content.AsyncTaskLoader} that | ||
* fetches and parses the Kodsnack Atom feed in the background. | ||
* | ||
* @author Erik Jansson<[email protected]> | ||
*/ | ||
public class EpisodeLoader extends AsyncTaskLoader<List<Episode>> { | ||
/** Logger tag. */ | ||
private static final String TAG = EpisodeLoader.class.getSimpleName(); | ||
|
||
private List<Episode> episodes; // The list of episodes from the Atom feed. | ||
|
||
public EpisodeLoader(Context context) { | ||
super(context); | ||
} | ||
|
||
@Override | ||
public List<Episode> loadInBackground() { | ||
// Check if we have already fetched the episodes. | ||
if (episodes != null) { | ||
return episodes; | ||
} | ||
|
||
try { | ||
episodes = AtomParser.parse("http://feedpress.me/kodsnack"); | ||
} catch (IOException e) { | ||
Log.e(TAG, e.toString()); | ||
} catch (XmlPullParserException | ParseException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
return episodes; | ||
} | ||
|
||
@Override | ||
protected void onStartLoading() { | ||
forceLoad(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package se.kodsnack; | ||
|
||
import android.support.v4.app.Fragment; | ||
import android.support.v4.app.FragmentManager; | ||
import android.support.v4.app.FragmentPagerAdapter; | ||
|
||
/** | ||
* Subclass of {@link android.support.v4.app.FragmentPagerAdapter} that keeps | ||
* track of one {@link LiveFragment} and one {@link EpisodeListFragment} in a | ||
* {@link android.support.v4.view.ViewPager}. | ||
* | ||
* @author Erik Jansson<[email protected]> | ||
*/ | ||
public class KodsnackPagerAdapter extends FragmentPagerAdapter { | ||
private static final int NUM_FRAGMENTS = 2; | ||
|
||
private final Fragment[] fragments; // List of fragments this adapter holds. | ||
private final String[] fragmentTitles; // Titles of the fragments'. | ||
|
||
public KodsnackPagerAdapter(FragmentManager fm) { | ||
super(fm); | ||
final LiveFragment liveFragment = new LiveFragment(); | ||
final EpisodeListFragment listFragment = new EpisodeListFragment(); | ||
|
||
fragments = new Fragment[NUM_FRAGMENTS]; | ||
fragments[0] = liveFragment; | ||
fragments[1] = listFragment; | ||
|
||
fragmentTitles = new String[NUM_FRAGMENTS]; | ||
fragmentTitles[0] = liveFragment.getTitle(); | ||
fragmentTitles[1] = listFragment.getTitle(); | ||
} | ||
|
||
@Override | ||
public Fragment getItem(int i) { | ||
if (i < NUM_FRAGMENTS) { | ||
return fragments[i]; | ||
} else { | ||
throw new IllegalArgumentException("Fragment index too big."); | ||
} | ||
} | ||
|
||
@Override | ||
public int getCount() { | ||
return NUM_FRAGMENTS; | ||
} | ||
|
||
@Override | ||
public String getPageTitle(int i) { | ||
if (i < NUM_FRAGMENTS) { | ||
return fragmentTitles[i]; | ||
} else { | ||
throw new IllegalArgumentException("Fragment index too big."); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,30 @@ | ||
package se.kodsnack; | ||
|
||
import android.app.Activity; | ||
import android.os.Bundle; | ||
import android.support.v4.app.FragmentActivity; | ||
import android.support.v4.view.PagerTabStrip; | ||
import android.support.v4.view.ViewPager; | ||
|
||
public class ListenActivity extends Activity { | ||
/** | ||
* The main activity that holds the {@link android.support.v4.view.ViewPager} | ||
* with the two fragments in it. | ||
* | ||
* @author Erik Jansson<[email protected]> | ||
*/ | ||
public class ListenActivity extends FragmentActivity { | ||
/* Logger tag. */ | ||
@SuppressWarnings("UnusedDeclaration") | ||
private static final String TAG = ListenActivity.class.getSimpleName(); | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setContentView(R.layout.activity_listen); | ||
} | ||
|
||
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager); | ||
final PagerTabStrip tabs = (PagerTabStrip) findViewById(R.id.pager_tab_strip); | ||
|
||
viewPager.setAdapter(new KodsnackPagerAdapter(getSupportFragmentManager())); | ||
tabs.setTabIndicatorColorResource(R.color.alternate_foreground); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.