Removed Exception Report Viewer
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="lib" path="/app/android-sdk-linux_86/extras/android/compatibility/v4/android-support-v4.jar"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
2
ExceptionReportViewer/.gitignore
vendored
2
ExceptionReportViewer/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
/gen
|
||||
/bin
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ExceptionReportViewer</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.TwentyCodes.android.ExceptionReportViewer"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="7" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name" >
|
||||
<activity
|
||||
android:name=".Main"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.TwentyCodes.android.exception.ExceptionReportActivity" >
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name="com.TwentyCodes.android.exception.ReportPostingService"
|
||||
android:enabled="true"
|
||||
android:process=":ExceptionReportingService" >
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,22 +0,0 @@
|
||||
# exceptionhandler.properties
|
||||
# @author ricky barrette <rickbarrette@gmail.com>
|
||||
# @author twenty codes <twentycodes@gmail.com>
|
||||
|
||||
# This file is used to tell the Exception Handler LIbrary how to file
|
||||
# new exception reports
|
||||
# HTTP ONLY
|
||||
#
|
||||
# Place this file in you project's assets folder and edit as needed
|
||||
#
|
||||
# server is the physical web address for your server
|
||||
# file is the path to your filing script
|
||||
# get is the path to your json retrieval script
|
||||
# app is the redmine project name
|
||||
# tracker is the redmine tracker
|
||||
server = http://rickbarrette.dyndns.org:8080/redmine/exceptionhandler
|
||||
app = test
|
||||
tracker = Bug
|
||||
|
||||
# uncomment the following if you want your application to use email to file reports.
|
||||
# if this is uncommented, email will always be used.
|
||||
#email = twentycodes@gmail.com
|
||||
@@ -1,3 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<lint>
|
||||
</lint>
|
||||
@@ -1,40 +0,0 @@
|
||||
-optimizationpasses 5
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontpreverify
|
||||
-verbose
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-9
|
||||
android.library.reference.1=../ExceptionHandlerLib
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.4 KiB |
@@ -1,52 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="#"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="#99CC00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="#99CC00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="#99CC00" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:textColor="#99CC00"
|
||||
android:textSize="10dip" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/msg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#000000"
|
||||
android:textSize="15dip" >
|
||||
</TextView>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<com.jakewharton.android.viewpagerindicator.TitlePageIndicator
|
||||
android:id="@+id/indicator"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dip" />
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:background="#ffffff" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string-array name="titles">
|
||||
<item>Production</item>
|
||||
<item>Testing</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Copyright (C) 2011 Patrik Åkerfeldt
|
||||
Copyright (C) 2011 Jake Wharton
|
||||
|
||||
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.
|
||||
-->
|
||||
<declare-styleable name="ViewPagerIndicator">
|
||||
<attr name="circlePageIndicatorStyle" format="reference" />
|
||||
<attr name="titlePageIndicatorStyle" format="reference" />
|
||||
</declare-styleable>
|
||||
<declare-styleable name="TitlePageIndicator">
|
||||
<attr name="clipPadding" format="dimension" />
|
||||
<attr name="footerColor" format="color" />
|
||||
<attr name="footerLineHeight" format="dimension" />
|
||||
<attr name="footerIndicatorStyle">
|
||||
<enum name="none" value="0" />
|
||||
<enum name="triangle" value="1" />
|
||||
<enum name="underline" value="2" />
|
||||
</attr>
|
||||
<attr name="footerIndicatorHeight" format="dimension" />
|
||||
<attr name="footerIndicatorPadding" format="dimension" />
|
||||
<attr name="footerIndicatorUnderlinePadding" format="dimension" />
|
||||
<attr name="selectedColor" format="color" />
|
||||
<attr name="selectedBold" format="boolean" />
|
||||
<attr name="textColor" format="color" />
|
||||
<attr name="textSize" format="dimension" />
|
||||
<attr name="titlePadding" format="dimension" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
@@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2011 Jake Wharton
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<dimen name="default_title_indicator_clip_padding">0dp</dimen>
|
||||
|
||||
<color name="default_title_indicator_footer_color">#FFFFFFFF</color>
|
||||
|
||||
<dimen name="default_title_indicator_footer_line_height">1px</dimen>
|
||||
|
||||
<integer name="default_title_indicator_footer_indicator_style">1</integer>
|
||||
|
||||
<dimen name="default_title_indicator_footer_indicator_height">7dp</dimen>
|
||||
<dimen name="default_title_indicator_footer_indicator_padding">5dp</dimen>
|
||||
<dimen name="default_title_indicator_footer_indicator_underline_padding">10dp</dimen>
|
||||
|
||||
<color name="default_title_indicator_selected_color">#FF99CC00</color>
|
||||
|
||||
<bool name="default_title_indicator_selected_bold">true</bool>
|
||||
|
||||
<color name="default_title_indicator_text_color">#FFFFFFFF</color>
|
||||
|
||||
<dimen name="default_title_indicator_text_size">18dp</dimen>
|
||||
<dimen name="default_title_indicator_title_padding">5dp</dimen>
|
||||
|
||||
</resources>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="hello">Hello World, Main!</string>
|
||||
<string name="app_name">ExceptionReportViewer</string>
|
||||
<string name="there_was_an_error">There was an error...</string>
|
||||
|
||||
</resources>
|
||||
@@ -1,62 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2011 Jake Wharton
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="StyledIndicators" parent="@android:style/Theme.Light">
|
||||
<item name="titlePageIndicatorStyle">@style/CustomTitlePageIndicator</item>
|
||||
</style>
|
||||
|
||||
<style name="CustomTitlePageIndicator">
|
||||
<item name="android:background">#FFDDDDDD</item>
|
||||
<item name="footerColor">#FFDDDDDD</item>
|
||||
<item name="footerLineHeight">2dp</item>
|
||||
<item name="footerIndicatorStyle">none</item>
|
||||
<item name="textColor">#FF999999</item>
|
||||
<item name="selectedColor">#00000000</item>
|
||||
<item name="selectedBold">false</item>
|
||||
</style>
|
||||
|
||||
<!-- Copyright (C) 2011 Jake Wharton 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. -->
|
||||
<style name="Theme.PageIndicatorDefaults" parent="@android:style/Theme">
|
||||
<item name="titlePageIndicatorStyle">@style/Widget.TitlePageIndicator</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.TitlePageIndicator" parent="@android:style/Widget">
|
||||
<item name="clipPadding">@dimen/default_title_indicator_clip_padding</item>
|
||||
<item name="footerColor">@color/default_title_indicator_footer_color</item>
|
||||
<item name="footerLineHeight">@dimen/default_title_indicator_footer_line_height</item>
|
||||
<item name="footerIndicatorStyle">
|
||||
@integer/default_title_indicator_footer_indicator_style
|
||||
</item>
|
||||
<item name="footerIndicatorHeight">
|
||||
@dimen/default_title_indicator_footer_indicator_height
|
||||
</item>
|
||||
<item name="footerIndicatorPadding">
|
||||
@dimen/default_title_indicator_footer_indicator_padding
|
||||
</item>
|
||||
<item name="footerIndicatorUnderlinePadding">
|
||||
@dimen/default_title_indicator_footer_indicator_underline_padding
|
||||
</item>
|
||||
<item name="selectedColor">@color/default_title_indicator_selected_color</item>
|
||||
<item name="selectedBold">@bool/default_title_indicator_selected_bold</item>
|
||||
<item name="textColor">@color/default_title_indicator_text_color</item>
|
||||
<item name="textSize">@dimen/default_title_indicator_text_size</item>
|
||||
<item name="titlePadding">@dimen/default_title_indicator_title_padding</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* JSONLoader.java
|
||||
* @date Dec 28, 2011
|
||||
* @author ricky barrette
|
||||
* @author Twenty Codes, LLC
|
||||
*/
|
||||
package com.TwentyCodes.android.ExceptionReportViewer;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
/**
|
||||
* This Loader will be used to download and parse a JSON object from the internet
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class JSONLoader extends Loader<JSONObject> {
|
||||
|
||||
private LoaderCallbacks<JSONObject> mListener;
|
||||
private String mUrl;
|
||||
private InputStream mContent;
|
||||
|
||||
/**
|
||||
* Creates an new JSONLoader
|
||||
* @param url
|
||||
* @param listener
|
||||
* @param context
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public JSONLoader(String url, LoaderManager.LoaderCallbacks<JSONObject> listener, Context context) {
|
||||
super(context);
|
||||
mListener = listener;
|
||||
mUrl = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.content.Loader#onAbandon()
|
||||
*/
|
||||
@Override
|
||||
protected void onAbandon() {
|
||||
super.onAbandon();
|
||||
if(mContent != null)
|
||||
try {
|
||||
mContent.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.content.Loader#onForceLoad()
|
||||
*/
|
||||
@Override
|
||||
protected void onForceLoad() {
|
||||
// TODO Auto-generated method stub
|
||||
super.onForceLoad();
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.content.Loader#onReset()
|
||||
*/
|
||||
@Override
|
||||
protected void onReset() {
|
||||
super.onReset();
|
||||
if(mContent != null)
|
||||
try {
|
||||
mContent.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if(mListener != null)
|
||||
mListener.onLoaderReset(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.content.Loader#onStartLoading()
|
||||
*/
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
super.onStartLoading();
|
||||
if(mListener != null)
|
||||
try {
|
||||
mListener.onLoadFinished(this, new JSONObject(downloadJSON(mUrl)));
|
||||
} catch (IllegalStateException e) {
|
||||
mListener.onLoadFinished(this, null);
|
||||
} catch (ClientProtocolException e) {
|
||||
mListener.onLoadFinished(this, null);
|
||||
} catch (JSONException e) {
|
||||
mListener.onLoadFinished(this, null);
|
||||
} catch (IOException e) {
|
||||
mListener.onLoadFinished(this, null);
|
||||
} catch (NullPointerException e) {
|
||||
mListener.onLoadFinished(this, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.content.Loader#onStopLoading()
|
||||
*/
|
||||
@Override
|
||||
protected void onStopLoading() {
|
||||
super.onStopLoading();
|
||||
if(mContent != null)
|
||||
try {
|
||||
mContent.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads exception report JSON from the Internet
|
||||
* @param url
|
||||
* @return
|
||||
* @throws IllegalStateException
|
||||
* @throws ClientProtocolException
|
||||
* @throws IOException
|
||||
* @author ricky barrette
|
||||
*/
|
||||
private String downloadJSON(String url) throws IllegalStateException, ClientProtocolException, IOException {
|
||||
if(url == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
StringBuffer response = new StringBuffer();
|
||||
mContent = new DefaultHttpClient().execute(new HttpGet(url)).getEntity().getContent();
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(mContent));
|
||||
String buff = null;
|
||||
while ((buff = br.readLine()) != null){
|
||||
System.out.print(buff);
|
||||
response.append(buff);
|
||||
}
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.TwentyCodes.android.ExceptionReportViewer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.TwentyCodes.android.exception.ExceptionHandler;
|
||||
import com.jakewharton.android.viewpagerindicator.TitlePageIndicator;
|
||||
import com.jakewharton.android.viewpagerindicator.TitledFragmentAdapter;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.view.ViewPager;
|
||||
|
||||
/**
|
||||
* This is the main activity of this application.
|
||||
* This application will be used to download and display the exception reports from a server.
|
||||
*
|
||||
* TODO Create settings activity and implement the following settings
|
||||
* + production url
|
||||
* + testing url
|
||||
* + version preference
|
||||
*
|
||||
* TODO Create icons for titled view pager
|
||||
*
|
||||
* TODO Update ReportListFragment to a dynamically load 10 reports, and retrieve more when necessary.
|
||||
* This will probably also entail server side changes
|
||||
*
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class Main extends FragmentActivity {
|
||||
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
|
||||
setContentView(R.layout.main);
|
||||
|
||||
Integer.parseInt("poop");
|
||||
|
||||
ArrayList<Fragment> fragments = new ArrayList<Fragment>();
|
||||
fragments.add(new ReportListFragment("http://powers.doesntexist.com:666/?get=1"));
|
||||
fragments.add(new ReportListFragment("http://powers.doesntexist.com:666/testing/?get=1"));
|
||||
|
||||
//the icons for the pages go here
|
||||
int[] icons = new int[]{
|
||||
//TODO create icons and update
|
||||
android.R.drawable.stat_sys_warning,
|
||||
android.R.drawable.stat_sys_warning
|
||||
};
|
||||
|
||||
//display the pages
|
||||
ViewPager pager = (ViewPager) findViewById(R.id.pager);
|
||||
pager.setAdapter(new TitledFragmentAdapter(this.getSupportFragmentManager(), fragments, this.getResources().getStringArray(R.array.titles), icons));
|
||||
|
||||
//display the titles
|
||||
TitlePageIndicator indicator = (TitlePageIndicator) findViewById(R.id.indicator);
|
||||
indicator.setViewPager(pager);
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/**
|
||||
* ReportAdapter.java
|
||||
* @date Dec 19, 2011
|
||||
* @author ricky barrette
|
||||
* @author Twenty Codes, LLC
|
||||
*/
|
||||
package com.TwentyCodes.android.ExceptionReportViewer;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* This adaptor will be used to populate a listview with report titles provided
|
||||
* a JSONArray
|
||||
*
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class ReportAdapter extends BaseAdapter {
|
||||
|
||||
private static final String TAG = "ReportAdapter";
|
||||
private JSONArray mReports;
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
/**
|
||||
* Creates a new ReportAdator
|
||||
*
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public ReportAdapter(Context context, JSONArray reports) {
|
||||
mReports = reports;
|
||||
mInflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the amount of reports in the reports JSONArray (non-Javadoc)
|
||||
*
|
||||
* @see android.widget.Adapter#getCount()
|
||||
*/
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mReports.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the report at index
|
||||
*
|
||||
* @param index
|
||||
* (non-Javadoc)
|
||||
* @see android.widget.Adapter#getItem(int)
|
||||
*/
|
||||
@Override
|
||||
public JSONObject getItem(int position) {
|
||||
try {
|
||||
return mReports.getJSONObject(position);
|
||||
} catch (JSONException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see android.widget.Adapter#getItemId(int)
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* this method will be used to populate the views (non-Javadoc)
|
||||
*
|
||||
* @see android.widget.Adapter#getView(int, android.view.View,
|
||||
* android.view.ViewGroup)
|
||||
*/
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
/*
|
||||
* here we will only create new views when needed, and recycle old ones
|
||||
* when provided
|
||||
*/
|
||||
Holder holder;
|
||||
if (convertView == null) {
|
||||
convertView = mInflater.inflate(R.layout.list_item, null);
|
||||
holder = new Holder();
|
||||
holder.id = (TextView) convertView.findViewById(R.id.id);
|
||||
holder.msg = (TextView) convertView.findViewById(R.id.msg);
|
||||
holder.status = (TextView) convertView.findViewById(R.id.status);
|
||||
holder.app = (TextView) convertView.findViewById(R.id.app);
|
||||
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (Holder) convertView.getTag();
|
||||
}
|
||||
|
||||
/*
|
||||
* here we will populate the views
|
||||
*/
|
||||
JSONObject report = null;
|
||||
try {
|
||||
report = getItem(position).getJSONObject("report");
|
||||
} catch (JSONException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
Log.d(TAG, report.toString());
|
||||
|
||||
try {
|
||||
holder.id.setText(report.getString("id"));
|
||||
} catch (JSONException e) {
|
||||
holder.id.setText(e.getMessage());
|
||||
}
|
||||
try {
|
||||
holder.msg.setText(report.getString("msg"));
|
||||
} catch (JSONException e) {
|
||||
holder.msg.setText(e.getMessage());
|
||||
}
|
||||
try {
|
||||
holder.status.setText(report.getString("status"));
|
||||
} catch (JSONException e) {
|
||||
holder.status.setText(e.getMessage());
|
||||
}
|
||||
try {
|
||||
holder.app.setText(report.getString("app"));
|
||||
} catch (JSONException e) {
|
||||
holder.app.setText(e.getMessage());
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
/**
|
||||
* This simple class will be used to hold views, so they can be recycled
|
||||
*
|
||||
* @author ricky barrette
|
||||
*/
|
||||
class Holder {
|
||||
TextView id;
|
||||
TextView status;
|
||||
TextView msg;
|
||||
TextView app;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/**
|
||||
* ReportListFragment.java
|
||||
* @date Dec 19, 2011
|
||||
* @author ricky barrette
|
||||
* @author Twenty Codes, LLC
|
||||
*/
|
||||
package com.TwentyCodes.android.ExceptionReportViewer;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.TwentyCodes.android.exception.ExceptionReportActivity;
|
||||
import com.TwentyCodes.android.exception.Report;
|
||||
|
||||
/**
|
||||
* This fragment will be used to display a list of exception reports to the user
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public class ReportListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<JSONObject> {
|
||||
|
||||
private JSONArray mReports;
|
||||
private String mUrl;
|
||||
|
||||
/**
|
||||
* Creates a new ReportListFragment
|
||||
* @param url of server
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public ReportListFragment(final String url) {
|
||||
super();
|
||||
mUrl = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.app.Fragment#onActivityCreated(android.os.Bundle)
|
||||
*/
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
this.setListShown(false);
|
||||
this.getListView().setCacheColorHint(Color.TRANSPARENT);
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user selects a report to display
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.app.ListFragment#onListItemClick(android.widget.ListView, android.view.View, int, long)
|
||||
*/
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
try {
|
||||
this.startActivity(new Intent(this.getActivity(), ExceptionReportActivity.class)
|
||||
.putExtra("display", true)
|
||||
.putExtra("report", new Report("").generateReport(mReports.getJSONObject(position).getJSONObject("report"))));
|
||||
} catch (JSONException e) {
|
||||
Toast.makeText(this.getActivity().getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the loader is created
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader(int, android.os.Bundle)
|
||||
*/
|
||||
@Override
|
||||
public Loader<JSONObject> onCreateLoader(int id, Bundle args) {
|
||||
return new JSONLoader(mUrl, this, this.getActivity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the loader has finished
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished(android.support.v4.content.Loader, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void onLoadFinished(Loader<JSONObject> loader, JSONObject jsonObject) {
|
||||
if(jsonObject != null){
|
||||
try {
|
||||
mReports = jsonObject.getJSONArray("reports");
|
||||
this.setListAdapter(new ReportAdapter(this.getActivity(), mReports));
|
||||
} catch (JSONException e) {
|
||||
this.setEmptyText(getText(R.string.there_was_an_error));
|
||||
}
|
||||
this.setEmptyText(getText(R.string.there_was_an_error));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the loader has been reset
|
||||
* (non-Javadoc)
|
||||
* @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset(android.support.v4.content.Loader)
|
||||
*/
|
||||
@Override
|
||||
public void onLoaderReset(Loader<JSONObject> loader) {
|
||||
//not Needed
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* FragmentAdapter.java
|
||||
* @date Aug 6, 2011
|
||||
* @author Twenty Codes, LLC
|
||||
* @author ricky barrette
|
||||
*/
|
||||
package com.jakewharton.android.viewpagerindicator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
|
||||
/**
|
||||
* This adaptor maintains the How and What fragments
|
||||
* @author ricky
|
||||
*/
|
||||
class FragmentAdapter extends FragmentPagerAdapter {
|
||||
|
||||
private ArrayList<Fragment> mFragments;
|
||||
|
||||
/**
|
||||
* Creates a new FragmentAdaptor
|
||||
* @param fm
|
||||
* @param fragments to be displayed
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public FragmentAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
|
||||
super(fm);
|
||||
this.mFragments = fragments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return this.mFragments.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return this.mFragments.size();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Patrik Akerfeldt
|
||||
* Copyright (C) 2011 Jake Wharton
|
||||
*
|
||||
* 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 com.jakewharton.android.viewpagerindicator;
|
||||
|
||||
import android.support.v4.view.ViewPager;
|
||||
|
||||
/**
|
||||
* A PageIndicator is responsible to show an visual indicator on the total views
|
||||
* number and the current visible view.
|
||||
*/
|
||||
public interface PageIndicator extends ViewPager.OnPageChangeListener {
|
||||
/**
|
||||
* Bind the indicator to a ViewPager.
|
||||
*
|
||||
* @param view
|
||||
*/
|
||||
public void setViewPager(ViewPager view);
|
||||
|
||||
/**
|
||||
* Bind the indicator to a ViewPager.
|
||||
*
|
||||
* @param view
|
||||
* @param initialPosition
|
||||
*/
|
||||
public void setViewPager(ViewPager view, int initialPosition);
|
||||
|
||||
/**
|
||||
* <p>Set the current page of both the ViewPager and indicator.</p>
|
||||
*
|
||||
* <p>This <strong>must</strong> be used if you need to set the page before
|
||||
* the views are drawn on screen (e.g., default start page).</p>
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public void setCurrentItem(int item);
|
||||
|
||||
/**
|
||||
* Set a page change listener which will receive forwarded events.
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
|
||||
}
|
||||
@@ -1,640 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Patrik Akerfeldt
|
||||
* Copyright (C) 2011 Francisco Figueiredo Jr.
|
||||
* Copyright (C) 2011 Jake Wharton
|
||||
*
|
||||
* 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 com.jakewharton.android.viewpagerindicator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.TwentyCodes.android.exception.R;
|
||||
|
||||
/**
|
||||
* A TitlePageIndicator is a PageIndicator which displays the title of left view
|
||||
* (if exist), the title of the current select view (centered) and the title of
|
||||
* the right view (if exist). When the user scrolls the ViewPager then titles are
|
||||
* also scrolled.
|
||||
*/
|
||||
public class TitlePageIndicator extends TextView implements PageIndicator, View.OnTouchListener {
|
||||
private static final float UNDERLINE_FADE_PERCENTAGE = 0.25f;
|
||||
|
||||
public enum IndicatorStyle {
|
||||
None(0), Triangle(1), Underline(2);
|
||||
|
||||
public final int value;
|
||||
|
||||
private IndicatorStyle(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static IndicatorStyle fromValue(int value) {
|
||||
for (IndicatorStyle style : IndicatorStyle.values()) {
|
||||
if (style.value == value) {
|
||||
return style;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ViewPager mViewPager;
|
||||
private ViewPager.OnPageChangeListener mListener;
|
||||
private TitleProvider mTitleProvider;
|
||||
private int mCurrentPage;
|
||||
private int mCurrentOffset;
|
||||
private final Paint mPaintText;
|
||||
private final Paint mPaintSelected;
|
||||
private Path mPath;
|
||||
private final Paint mPaintFooterLine;
|
||||
private IndicatorStyle mFooterIndicatorStyle;
|
||||
private final Paint mPaintFooterIndicator;
|
||||
private float mFooterIndicatorHeight;
|
||||
private float mFooterIndicatorPadding;
|
||||
private float mFooterIndicatorUnderlinePadding;
|
||||
private float mTitlePadding;
|
||||
/** Left and right side padding for not active view titles. */
|
||||
private float mClipPadding;
|
||||
private float mFooterLineHeight;
|
||||
|
||||
|
||||
public TitlePageIndicator(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TitlePageIndicator(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.titlePageIndicatorStyle);
|
||||
}
|
||||
|
||||
public TitlePageIndicator(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
super.setOnTouchListener(this);
|
||||
|
||||
//Load defaults from resources
|
||||
final Resources res = getResources();
|
||||
final int defaultFooterColor = res.getColor(R.color.default_title_indicator_footer_color);
|
||||
final float defaultFooterLineHeight = res.getDimension(R.dimen.default_title_indicator_footer_line_height);
|
||||
final int defaultFooterIndicatorStyle = res.getInteger(R.integer.default_title_indicator_footer_indicator_style);
|
||||
final float defaultFooterIndicatorHeight = res.getDimension(R.dimen.default_title_indicator_footer_indicator_height);
|
||||
final float defaultFooterIndicatorPadding = res.getDimension(R.dimen.default_title_indicator_footer_indicator_padding);
|
||||
final float defaultFooterIndicatorUnderlinePadding = res.getDimension(R.dimen.default_title_indicator_footer_indicator_underline_padding);
|
||||
final int defaultSelectedColor = res.getColor(R.color.default_title_indicator_selected_color);
|
||||
final boolean defaultSelectedBold = res.getBoolean(R.bool.default_title_indicator_selected_bold);
|
||||
final int defaultTextColor = res.getColor(R.color.default_title_indicator_text_color);
|
||||
final float defaultTextSize = res.getDimension(R.dimen.default_title_indicator_text_size);
|
||||
final float defaultTitlePadding = res.getDimension(R.dimen.default_title_indicator_title_padding);
|
||||
final float defaultClipPadding = res.getDimension(R.dimen.default_title_indicator_clip_padding);
|
||||
|
||||
//Retrieve styles attributes
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitlePageIndicator, defStyle, R.style.Widget_TitlePageIndicator);
|
||||
|
||||
//Retrieve the colors to be used for this view and apply them.
|
||||
mFooterLineHeight = a.getDimension(R.styleable.TitlePageIndicator_footerLineHeight, defaultFooterLineHeight);
|
||||
mFooterIndicatorStyle = IndicatorStyle.fromValue(a.getInteger(R.styleable.TitlePageIndicator_footerIndicatorStyle, defaultFooterIndicatorStyle));
|
||||
mFooterIndicatorHeight = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorHeight, defaultFooterIndicatorHeight);
|
||||
mFooterIndicatorPadding = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorPadding, defaultFooterIndicatorPadding);
|
||||
mFooterIndicatorUnderlinePadding = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorUnderlinePadding, defaultFooterIndicatorUnderlinePadding);
|
||||
mTitlePadding = a.getDimension(R.styleable.TitlePageIndicator_titlePadding, defaultTitlePadding);
|
||||
mClipPadding = a.getDimension(R.styleable.TitlePageIndicator_clipPadding, defaultClipPadding);
|
||||
|
||||
final float textSize = a.getDimension(R.styleable.TitlePageIndicator_textSize, defaultTextSize);
|
||||
final int footerColor = a.getColor(R.styleable.TitlePageIndicator_footerColor, defaultFooterColor);
|
||||
mPaintText = new Paint();
|
||||
mPaintText.setColor(a.getColor(R.styleable.TitlePageIndicator_textColor, defaultTextColor));
|
||||
mPaintText.setTextSize(textSize);
|
||||
mPaintText.setAntiAlias(true);
|
||||
mPaintSelected = new Paint();
|
||||
mPaintSelected.setColor(a.getColor(R.styleable.TitlePageIndicator_selectedColor, defaultSelectedColor));
|
||||
mPaintSelected.setTextSize(textSize);
|
||||
mPaintSelected.setFakeBoldText(a.getBoolean(R.styleable.TitlePageIndicator_selectedBold, defaultSelectedBold));
|
||||
mPaintSelected.setAntiAlias(true);
|
||||
mPaintFooterLine = new Paint();
|
||||
mPaintFooterLine.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
mPaintFooterLine.setStrokeWidth(mFooterLineHeight);
|
||||
mPaintFooterLine.setColor(footerColor);
|
||||
mPaintFooterIndicator = new Paint();
|
||||
mPaintFooterIndicator.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
mPaintFooterIndicator.setColor(footerColor);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
|
||||
public int getFooterColor() {
|
||||
return mPaintFooterLine.getColor();
|
||||
}
|
||||
|
||||
public void setFooterColor(int footerColor) {
|
||||
mPaintFooterLine.setColor(footerColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getFooterLineHeight() {
|
||||
return mFooterLineHeight;
|
||||
}
|
||||
|
||||
public void setFooterLineHeight(float footerLineHeight) {
|
||||
mFooterLineHeight = footerLineHeight;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getFooterIndicatorHeight() {
|
||||
return mFooterIndicatorHeight;
|
||||
}
|
||||
|
||||
public void setFooterIndicatorHeight(float footerTriangleHeight) {
|
||||
mFooterIndicatorHeight = footerTriangleHeight;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public IndicatorStyle getFooterIndicatorStyle() {
|
||||
return mFooterIndicatorStyle;
|
||||
}
|
||||
|
||||
public void setFooterIndicatorStyle(IndicatorStyle indicatorStyle) {
|
||||
mFooterIndicatorStyle = indicatorStyle;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public int getSelectedColor() {
|
||||
return mPaintSelected.getColor();
|
||||
}
|
||||
|
||||
public void setSelectedColor(int selectedColor) {
|
||||
mPaintSelected.setColor(selectedColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public boolean isSelectedBold() {
|
||||
return mPaintSelected.isFakeBoldText();
|
||||
}
|
||||
|
||||
public void setSelectedBold(boolean selectedBold) {
|
||||
mPaintSelected.setFakeBoldText(selectedBold);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public int getTextColor() {
|
||||
return mPaintText.getColor();
|
||||
}
|
||||
|
||||
public void setTextColor(int textColor) {
|
||||
mPaintText.setColor(textColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getTextSize() {
|
||||
return mPaintText.getTextSize();
|
||||
}
|
||||
|
||||
public void setTextSize(float textSize) {
|
||||
mPaintText.setTextSize(textSize);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getTitlePadding() {
|
||||
return this.mTitlePadding;
|
||||
}
|
||||
|
||||
public void setTitlePadding(float titlePadding) {
|
||||
mTitlePadding = titlePadding;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getClipPadding() {
|
||||
return this.mClipPadding;
|
||||
}
|
||||
|
||||
public void setClipPadding(float clipPadding) {
|
||||
mClipPadding = clipPadding;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see android.view.View#onDraw(android.graphics.Canvas)
|
||||
*/
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
//Calculate views bounds
|
||||
ArrayList<Rect> bounds = calculateAllBounds(mPaintText);
|
||||
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
final int countMinusOne = count - 1;
|
||||
final int halfWidth = getWidth() / 2;
|
||||
final int left = getLeft();
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
final int leftPlusWidth = left + width;
|
||||
|
||||
//Verify if the current view must be clipped to the screen
|
||||
Rect curViewBound = bounds.get(mCurrentPage);
|
||||
int curViewWidth = curViewBound.right - curViewBound.left;
|
||||
if (curViewBound.left < 0) {
|
||||
//Try to clip to the screen (left side)
|
||||
clipViewOnTheLeft(curViewBound, curViewWidth);
|
||||
}
|
||||
if (curViewBound.right > leftPlusWidth) {
|
||||
//Try to clip to the screen (right side)
|
||||
clipViewOnTheRight(curViewBound, curViewWidth, leftPlusWidth);
|
||||
}
|
||||
|
||||
//Left views starting from the current position
|
||||
if (mCurrentPage > 0) {
|
||||
for (int i = mCurrentPage - 1; i >= 0; i--) {
|
||||
Rect bound = bounds.get(i);
|
||||
int w = bound.right - bound.left;
|
||||
//Is left side is outside the screen
|
||||
if (bound.left < 0) {
|
||||
//Try to clip to the screen (left side)
|
||||
clipViewOnTheLeft(bound, w);
|
||||
//Except if there's an intersection with the right view
|
||||
if (i < countMinusOne && mCurrentPage != i) {
|
||||
Rect rightBound = bounds.get(i + 1);
|
||||
//Intersection
|
||||
if (bound.right + (int)mTitlePadding > rightBound.left) {
|
||||
bound.left = rightBound.left - (w + (int)mTitlePadding);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Right views starting from the current position
|
||||
if (mCurrentPage < countMinusOne) {
|
||||
for (int i = mCurrentPage + 1 ; i < count; i++) {
|
||||
Rect bound = bounds.get(i);
|
||||
int w = bound.right - bound.left;
|
||||
//If right side is outside the screen
|
||||
if (bound.right > leftPlusWidth) {
|
||||
//Try to clip to the screen (right side)
|
||||
clipViewOnTheRight(bound, w, leftPlusWidth);
|
||||
//Except if there's an intersection with the left view
|
||||
if (i > 0 && mCurrentPage != i) {
|
||||
Rect leftBound = bounds.get(i - 1);
|
||||
//Intersection
|
||||
if (bound.left - (int)mTitlePadding < leftBound.right) {
|
||||
bound.left = leftBound.right + (int)mTitlePadding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap icon = null;
|
||||
//Now draw views
|
||||
for (int i = 0; i < count; i++) {
|
||||
//Get the title
|
||||
Rect bound = bounds.get(i);
|
||||
//Only if one side is visible
|
||||
if ((bound.left > left && bound.left < leftPlusWidth) || (bound.right > left && bound.right < leftPlusWidth)) {
|
||||
Paint paint = mPaintText;
|
||||
//Change the color is the title is closed to the center
|
||||
int middle = (bound.left + bound.right) / 2;
|
||||
if (Math.abs(middle - halfWidth) < 20) {
|
||||
paint = mPaintSelected;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw the icons
|
||||
* @author ricky barrette
|
||||
*/
|
||||
icon = BitmapFactory.decodeResource( getResources(), mTitleProvider.getIcon(i));;
|
||||
canvas.drawBitmap(icon, bound.left - (icon.getWidth() + 4), (bound.bottom - (icon.getHeight() / 2) )-mFooterIndicatorHeight , paint);
|
||||
canvas.drawText(mTitleProvider.getTitle(i), bound.left, bound.bottom, paint);
|
||||
}
|
||||
}
|
||||
|
||||
//Draw the footer line
|
||||
mPath = new Path();
|
||||
mPath.moveTo(0, height - mFooterLineHeight);
|
||||
mPath.lineTo(width, height - mFooterLineHeight);
|
||||
mPath.close();
|
||||
canvas.drawPath(mPath, mPaintFooterLine);
|
||||
|
||||
switch (mFooterIndicatorStyle) {
|
||||
case Triangle:
|
||||
mPath = new Path();
|
||||
mPath.moveTo(halfWidth, height - mFooterLineHeight - mFooterIndicatorHeight);
|
||||
mPath.lineTo(halfWidth + mFooterIndicatorHeight, height - mFooterLineHeight);
|
||||
mPath.lineTo(halfWidth - mFooterIndicatorHeight, height - mFooterLineHeight);
|
||||
mPath.close();
|
||||
canvas.drawPath(mPath, mPaintFooterIndicator);
|
||||
break;
|
||||
|
||||
case Underline:
|
||||
float deltaPercentage = mCurrentOffset * 1.0f / width;
|
||||
int alpha = 0xFF;
|
||||
int page = mCurrentPage;
|
||||
if (deltaPercentage <= UNDERLINE_FADE_PERCENTAGE) {
|
||||
alpha = (int)(0xFF * ((UNDERLINE_FADE_PERCENTAGE - deltaPercentage) / UNDERLINE_FADE_PERCENTAGE));
|
||||
} else if (deltaPercentage >= (1 - UNDERLINE_FADE_PERCENTAGE)) {
|
||||
alpha = (int)(0xFF * ((deltaPercentage - (1 - UNDERLINE_FADE_PERCENTAGE)) / UNDERLINE_FADE_PERCENTAGE));
|
||||
page += 1; //We are coming into the next page
|
||||
} else if (mCurrentOffset != 0) {
|
||||
break; //Not in underline scope
|
||||
}
|
||||
|
||||
Rect underlineBounds = bounds.get(page);
|
||||
mPath = new Path();
|
||||
mPath.moveTo(underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight);
|
||||
mPath.lineTo(underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight);
|
||||
mPath.lineTo(underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight - mFooterIndicatorHeight);
|
||||
mPath.lineTo(underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight - mFooterIndicatorHeight);
|
||||
mPath.close();
|
||||
|
||||
mPaintFooterIndicator.setAlpha(alpha);
|
||||
canvas.drawPath(mPath, mPaintFooterIndicator);
|
||||
mPaintFooterIndicator.setAlpha(0xFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean onTouch(View view, MotionEvent event) {
|
||||
if ((view != this) || (event.getAction() != MotionEvent.ACTION_DOWN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
final float halfWidth = getWidth() / 2;
|
||||
final float sixthWidth = getWidth() / 6;
|
||||
|
||||
if ((mCurrentPage > 0) && (event.getX() < halfWidth - sixthWidth)) {
|
||||
mViewPager.setCurrentItem(mCurrentPage - 1);
|
||||
return true;
|
||||
} else if ((mCurrentPage < count - 1) && (event.getX() > halfWidth + sixthWidth)) {
|
||||
mViewPager.setCurrentItem(mCurrentPage + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setOnTouchListener(OnTouchListener listener) {
|
||||
throw new UnsupportedOperationException("This view does not support listening to its touch events.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bounds for the right textView including clip padding.
|
||||
*
|
||||
* @param curViewBound
|
||||
* current bounds.
|
||||
* @param curViewWidth
|
||||
* width of the view.
|
||||
*/
|
||||
private void clipViewOnTheRight(Rect curViewBound, int curViewWidth, int leftPlusWidth) {
|
||||
curViewBound.right = leftPlusWidth - (int)mClipPadding;
|
||||
curViewBound.left = curViewBound.right - curViewWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bounds for the left textView including clip padding.
|
||||
*
|
||||
* @param curViewBound
|
||||
* current bounds.
|
||||
* @param curViewWidth
|
||||
* width of the view.
|
||||
*/
|
||||
private void clipViewOnTheLeft(Rect curViewBound, int curViewWidth) {
|
||||
curViewBound.left = 0 + (int)mClipPadding;
|
||||
curViewBound.right = curViewWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate views bounds and scroll them according to the current index
|
||||
*
|
||||
* @param paint
|
||||
* @param currentIndex
|
||||
* @return
|
||||
*/
|
||||
private ArrayList<Rect> calculateAllBounds(Paint paint) {
|
||||
ArrayList<Rect> list = new ArrayList<Rect>();
|
||||
//For each views (If no values then add a fake one)
|
||||
final int count = mViewPager.getAdapter().getCount();
|
||||
final int width = getWidth();
|
||||
final int halfWidth = width / 2;
|
||||
for (int i = 0; i < count; i++) {
|
||||
Rect bounds = calcBounds(i, paint);
|
||||
int w = (bounds.right - bounds.left);
|
||||
int h = (bounds.bottom - bounds.top);
|
||||
bounds.left = (halfWidth) - (w / 2) - mCurrentOffset + ((i - mCurrentPage) * width);
|
||||
bounds.right = bounds.left + w;
|
||||
bounds.top = 0;
|
||||
bounds.bottom = h;
|
||||
list.add(bounds);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the bounds for a view's title
|
||||
*
|
||||
* @param index
|
||||
* @param paint
|
||||
* @return
|
||||
*/
|
||||
private Rect calcBounds(int index, Paint paint) {
|
||||
//Calculate the text bounds
|
||||
Rect bounds = new Rect();
|
||||
bounds.right = (int)paint.measureText(mTitleProvider.getTitle(index));
|
||||
bounds.bottom = (int)(paint.descent() - paint.ascent());
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewPager(ViewPager view) {
|
||||
if (view.getAdapter() == null) {
|
||||
throw new IllegalStateException("ViewPager does not have adapter instance.");
|
||||
}
|
||||
if (!(view.getAdapter() instanceof TitleProvider)) {
|
||||
throw new IllegalStateException("ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
|
||||
}
|
||||
mViewPager = view;
|
||||
mViewPager.setOnPageChangeListener(this);
|
||||
mTitleProvider = (TitleProvider)mViewPager.getAdapter();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewPager(ViewPager view, int initialPosition) {
|
||||
setViewPager(view);
|
||||
setCurrentItem(initialPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentItem(int item) {
|
||||
if (mViewPager == null) {
|
||||
throw new IllegalStateException("ViewPager has not been bound.");
|
||||
}
|
||||
mViewPager.setCurrentItem(item);
|
||||
mCurrentPage = item;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
if (mListener != null) {
|
||||
mListener.onPageScrollStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
mCurrentPage = position;
|
||||
mCurrentOffset = positionOffsetPixels;
|
||||
invalidate();
|
||||
|
||||
if (mListener != null) {
|
||||
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
if (mListener != null) {
|
||||
mListener.onPageSelected(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see android.view.View#onMeasure(int, int)
|
||||
*/
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the width of this view
|
||||
*
|
||||
* @param measureSpec
|
||||
* A measureSpec packed into an int
|
||||
* @return The width of the view, honoring constraints from measureSpec
|
||||
*/
|
||||
private int measureWidth(int measureSpec) {
|
||||
int result = 0;
|
||||
int specMode = MeasureSpec.getMode(measureSpec);
|
||||
int specSize = MeasureSpec.getSize(measureSpec);
|
||||
|
||||
if (specMode != MeasureSpec.EXACTLY) {
|
||||
throw new IllegalStateException(getClass().getSimpleName() + " can only be used in EXACTLY mode.");
|
||||
}
|
||||
result = specSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the height of this view
|
||||
*
|
||||
* @param measureSpec
|
||||
* A measureSpec packed into an int
|
||||
* @return The height of the view, honoring constraints from measureSpec
|
||||
*/
|
||||
private int measureHeight(int measureSpec) {
|
||||
float result = 0;
|
||||
int specMode = MeasureSpec.getMode(measureSpec);
|
||||
int specSize = MeasureSpec.getSize(measureSpec);
|
||||
|
||||
if (specMode == MeasureSpec.EXACTLY) {
|
||||
//We were told how big to be
|
||||
result = specSize;
|
||||
} else {
|
||||
//Calculate the text bounds
|
||||
Rect bounds = new Rect();
|
||||
bounds.bottom = (int) (mPaintText.descent()-mPaintText.ascent());
|
||||
result = bounds.bottom - bounds.top + mFooterLineHeight;
|
||||
if (mFooterIndicatorStyle != IndicatorStyle.None) {
|
||||
result += mFooterIndicatorHeight + mFooterIndicatorPadding;
|
||||
}
|
||||
}
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state) {
|
||||
SavedState savedState = (SavedState)state;
|
||||
super.onRestoreInstanceState(savedState.getSuperState());
|
||||
mCurrentPage = savedState.currentPage;
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState() {
|
||||
setFreezesText(true);
|
||||
Parcelable superState = super.onSaveInstanceState();
|
||||
SavedState savedState = new SavedState(superState);
|
||||
savedState.currentPage = mCurrentPage;
|
||||
return savedState;
|
||||
}
|
||||
|
||||
static class SavedState extends BaseSavedState {
|
||||
int currentPage;
|
||||
|
||||
public SavedState(Parcelable superState) {
|
||||
super(superState);
|
||||
}
|
||||
|
||||
private SavedState(Parcel in) {
|
||||
super(in);
|
||||
currentPage = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeInt(currentPage);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
|
||||
@Override
|
||||
public SavedState createFromParcel(Parcel in) {
|
||||
return new SavedState(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SavedState[] newArray(int size) {
|
||||
return new SavedState[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Patrik Akerfeldt
|
||||
*
|
||||
* 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 com.jakewharton.android.viewpagerindicator;
|
||||
|
||||
/**
|
||||
* A TitleProvider provides the title to display according to a view.
|
||||
*/
|
||||
public interface TitleProvider {
|
||||
/**
|
||||
* Returns the title of the view at position
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
public String getTitle(int position);
|
||||
|
||||
/**
|
||||
* returns the icon res id of the view at position
|
||||
* @param postion
|
||||
* @return
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public int getIcon(int postion);
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
* TitleFragmentAdapter.java
|
||||
* @date Aug 6, 2011
|
||||
* @author Twenty Codes, LLC
|
||||
* @author ricky barrette
|
||||
*/
|
||||
package com.jakewharton.android.viewpagerindicator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
|
||||
|
||||
/**
|
||||
* This adaptor maintains a ViewPager title indicator.
|
||||
* @author ricky
|
||||
*/
|
||||
public class TitledFragmentAdapter extends FragmentAdapter implements TitleProvider {
|
||||
|
||||
private String[] mTitles;
|
||||
private int[] mIcons;
|
||||
|
||||
/**
|
||||
* Creates a new TitleFragmentAdapter
|
||||
* @param fm
|
||||
* @param fragments to be displayed
|
||||
* @param titles for the fragments
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public TitledFragmentAdapter(FragmentManager fm, ArrayList<Fragment> fragments, String[] titles, int[] icons) {
|
||||
super(fm, fragments);
|
||||
this.mTitles = titles;
|
||||
this.mIcons = icons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle(int position) {
|
||||
return this.mTitles[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIcon(int position) {
|
||||
return this.mIcons[position];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user