├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── misc.xml ├── modules.xml ├── scopes │ └── scope_settings.xml └── vcs.xml ├── GifAssistant.iml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── libs │ ├── android-support-v4.jar │ ├── android-support-v7-appcompat.jar │ ├── floatingactionbutton-1.9.0.aar │ └── nineoldandroids-library-2.4.0.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wind │ │ └── gifassistant │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── Satisfy-Regular.ttf │ ├── java │ └── com │ │ ├── chenupt │ │ └── springindicator │ │ │ ├── Point.java │ │ │ ├── SpringIndicator.java │ │ │ ├── SpringView.java │ │ │ ├── TabClickListener.java │ │ │ └── viewpager │ │ │ ├── FixedSpeedScroller.java │ │ │ └── ScrollerViewPager.java │ │ ├── handmark │ │ └── pulltorefresh │ │ │ └── library │ │ │ ├── ILoadingLayout.java │ │ │ ├── IPullToRefresh.java │ │ │ ├── LoadingLayoutProxy.java │ │ │ ├── OverscrollHelper.java │ │ │ ├── PullToRefreshAdapterViewBase.java │ │ │ ├── PullToRefreshBase.java │ │ │ ├── PullToRefreshExpandableListView.java │ │ │ ├── PullToRefreshGridView.java │ │ │ ├── PullToRefreshHorizontalScrollView.java │ │ │ ├── PullToRefreshListView.java │ │ │ ├── PullToRefreshScrollView.java │ │ │ ├── PullToRefreshWebView.java │ │ │ ├── extras │ │ │ ├── PullToRefreshWebView2.java │ │ │ └── SoundPullEventListener.java │ │ │ └── internal │ │ │ ├── EmptyViewMethodAccessor.java │ │ │ ├── FlipLoadingLayout.java │ │ │ ├── IndicatorLayout.java │ │ │ ├── LoadingLayout.java │ │ │ ├── RotateLoadingLayout.java │ │ │ ├── Utils.java │ │ │ └── ViewCompat.java │ │ ├── ryanharter │ │ └── viewpager │ │ │ ├── PagerAdapter.java │ │ │ └── ViewPager.java │ │ ├── special │ │ └── ResideMenu │ │ │ ├── LICENSE │ │ │ ├── ResideMenu.java │ │ │ ├── ResideMenuItem.java │ │ │ └── TouchDisableView.java │ │ └── wind │ │ ├── ffmpeghelper │ │ ├── FFmpegCommandBuilder.java │ │ └── FFmpegNativeHelper.java │ │ └── gifassistant │ │ ├── GifAssistantApp.java │ │ ├── data │ │ ├── ExtractPicturesWorker.java │ │ ├── GifProductInfo.java │ │ ├── GifProductsScanTask.java │ │ ├── VideosFilesScanTask.java │ │ └── VideosInfo.java │ │ ├── gifworker │ │ └── GifMerger.java │ │ ├── ui │ │ ├── DataLoadCallBack.java │ │ ├── GifProductsListAdapter.java │ │ ├── GifProductsListFragment.java │ │ ├── GifScaleSettingDialog.java │ │ ├── GifShowActivity.java │ │ ├── ListContextMenuListener.java │ │ ├── MainActivity.java │ │ ├── MaxTimeRangSettingListener.java │ │ ├── RangSettingDialog.java │ │ ├── RangSettingListener.java │ │ ├── RangValues.java │ │ ├── RateRangSettingListener.java │ │ ├── SettingFragment.java │ │ ├── VideoPlayerActivity.java │ │ ├── VideosListAdapter.java │ │ ├── VideosListFragment.java │ │ ├── WelcomeActivity.java │ │ ├── naviwelcome │ │ │ └── NavigationWelcomeActivity.java │ │ └── textpicker │ │ │ ├── Scroller.java │ │ │ └── TextPicker.java │ │ ├── utils │ │ ├── AppConfigs.java │ │ ├── AppCrashHandler.java │ │ └── AppUtils.java │ │ └── views │ │ ├── SoundView.java │ │ ├── VideoView.java │ │ ├── gifview │ │ ├── GifAction.java │ │ ├── GifDecoder.java │ │ ├── GifFrame.java │ │ └── GifView.java │ │ └── waveview │ │ ├── LICENSE │ │ ├── Titanic.java │ │ ├── TitanicTextView.java │ │ └── Typefaces.java │ ├── jniLibs │ └── armeabi │ │ ├── libavcodec-56.so │ │ ├── libavdevice-56.so │ │ ├── libavfilter-5.so │ │ ├── libavformat-56.so │ │ ├── libavutil-54.so │ │ ├── libffmpegjni.so │ │ ├── libswresample-1.so │ │ └── libswscale-3.so │ └── res │ ├── anim │ ├── nav_1_battery_rotate.xml │ ├── nav_1_zoom_top.xml │ ├── nav_2_everything_show.xml │ ├── navigation_next_icon_animation.xml │ ├── slide_in_from_bottom.xml │ ├── slide_in_from_top.xml │ ├── slide_out_to_bottom.xml │ ├── slide_out_to_top.xml │ └── welcome_alpha.xml │ ├── drawable-ldpi │ └── ic_launcher.png │ ├── drawable │ ├── checkbox_selector.xml │ ├── corners_bg.xml │ ├── corners_bottom_bg.xml │ ├── corners_bottom_pressed_bg.xml │ ├── corners_bottom_selector_bg.xml │ ├── corners_pressed_bg.xml │ ├── corners_selector_bg.xml │ ├── corners_top_bg.xml │ ├── corners_top_pressed_bg.xml │ ├── corners_top_selector_bg.xml │ ├── dialog_background.xml │ ├── fab_label_background.xml │ ├── indicator_bg_bottom.xml │ ├── indicator_bg_top.xml │ ├── item_background_holo_dark.xml │ ├── item_background_holo_light.xml │ ├── list_selector_background_transition_holo_dark.xml │ ├── list_selector_background_transition_holo_light.xml │ ├── nav_1_time_show_animation.xml │ ├── nav_3_rocket_animation.xml │ ├── nav_4_button.xml │ ├── reside_menu_text_selector.xml │ ├── skip_button.xml │ └── titlebar_menu_selector.xml │ ├── layout │ ├── gif_products_list_item.xml │ ├── gif_quality_setting_dialog.xml │ ├── gif_show_activity.xml │ ├── main_activity.xml │ ├── main_screen_pager_fragment.xml │ ├── navigation_1_layout.xml │ ├── navigation_2_layout.xml │ ├── navigation_3_layout.xml │ ├── navigation_4_layout.xml │ ├── navigation_welcome_activity.xml │ ├── number_picker_with_selector_wheel.xml │ ├── pull_to_refresh_header_horizontal.xml │ ├── pull_to_refresh_header_vertical.xml │ ├── rang_setting_dialog.xml │ ├── residemenu.xml │ ├── residemenu_item.xml │ ├── setting_fragment.xml │ ├── video_player.xml │ ├── video_player_controler.xml │ ├── videos_list_item.xml │ ├── wave_process_layout.xml │ └── welcome.xml │ ├── mipmap-hdpi │ ├── checkbox_normal.png │ ├── checkbox_pressed.png │ ├── default_ptr_flip.png │ ├── default_ptr_rotate.png │ ├── eject.png │ ├── eject_done.png │ ├── ic_backgroud_setting.png │ ├── ic_fab_delete.png │ ├── ic_fab_setting.png │ ├── ic_fab_shared.png │ ├── ic_gif_frame_rate.png │ ├── ic_gif_scale.png │ ├── ic_launcher.png │ ├── ic_time_length.png │ ├── icon_calendar.png │ ├── icon_home.png │ ├── icon_profile.png │ ├── icon_settings.png │ ├── indicator_arrow.png │ ├── list_focused_holo.9.png │ ├── list_longpressed_holo.9.png │ ├── list_pressed_holo_dark.9.png │ ├── list_pressed_holo_light.9.png │ ├── list_selector_disabled_holo_dark.9.png │ ├── list_selector_disabled_holo_light.9.png │ ├── menu_background.png │ ├── np_numberpicker_selection_divider.9.png │ ├── pause.png │ ├── play.png │ ├── shadow.9.png │ ├── skip_backgroud.png │ ├── skip_button_normal.png │ ├── skip_button_pressed.png │ ├── sound_line.bmp │ ├── sound_line1.bmp │ ├── sounddisable.png │ ├── soundenable.png │ ├── title_bar_menu.png │ ├── title_bar_menu_on.png │ ├── wave.png │ └── welcome_mark.jpg │ ├── mipmap-mdpi │ ├── default_ptr_flip.png │ ├── default_ptr_rotate.png │ ├── ic_backgroud_setting.png │ ├── ic_fab_delete.png │ ├── ic_fab_setting.png │ ├── ic_fab_shared.png │ ├── ic_gif_frame_rate.png │ ├── ic_gif_scale.png │ ├── ic_launcher.png │ ├── ic_time_length.png │ ├── indicator_arrow.png │ ├── list_focused_holo.9.png │ ├── list_longpressed_holo.9.png │ ├── list_pressed_holo_dark.9.png │ ├── list_pressed_holo_light.9.png │ ├── list_selector_disabled_holo_dark.9.png │ ├── list_selector_disabled_holo_light.9.png │ └── np_numberpicker_selection_divider.9.png │ ├── mipmap-xhdpi │ ├── default_ptr_flip.png │ ├── default_ptr_rotate.png │ ├── ic_backgroud_setting.png │ ├── ic_fab_delete.png │ ├── ic_fab_setting.png │ ├── ic_fab_shared.png │ ├── ic_gif_frame_rate.png │ ├── ic_gif_scale.png │ ├── ic_launcher.png │ ├── ic_time_length.png │ ├── indicator_arrow.png │ ├── list_focused_holo.9.png │ ├── list_longpressed_holo.9.png │ ├── list_pressed_holo_dark.9.png │ ├── list_pressed_holo_light.9.png │ ├── list_selector_disabled_holo_dark.9.png │ ├── list_selector_disabled_holo_light.9.png │ ├── nav_1_battery_image.png │ ├── nav_1_note_text.png │ ├── nav_1_time_show_image_1.png │ ├── nav_1_time_show_image_2.png │ ├── nav_1_top_static_image.png │ ├── nav_1_watch_static_image.png │ ├── nav_2_everything_show.png │ ├── nav_2_static_backgroud.png │ ├── nav_2_text.png │ ├── nav_2_top_static.png │ ├── nav_3_bottom_static.png │ ├── nav_3_cloud_1.png │ ├── nav_3_cloud_2.png │ ├── nav_3_cloud_3.png │ ├── nav_3_cloud_4.png │ ├── nav_3_top_static.png │ ├── nav_4_bottom_text.png │ ├── nav_4_button_start_normal.png │ ├── nav_4_button_start_pressed.png │ ├── nav_4_zhaopai.png │ ├── next_icon.png │ ├── np_numberpicker_selection_divider.9.png │ ├── rocket_long.png │ ├── rocket_middle.png │ └── rocket_short.png │ ├── mipmap-xxhdpi │ ├── ic_backgroud_setting.png │ ├── ic_fab_delete.png │ ├── ic_fab_setting.png │ ├── ic_fab_shared.png │ ├── ic_gif_frame_rate.png │ ├── ic_gif_scale.png │ ├── ic_launcher.png │ └── ic_time_length.png │ ├── values-v11 │ └── styles.xml │ ├── values-v14 │ └── styles.xml │ ├── values-zh │ ├── pull_refresh_strings.xml │ └── strings.xml │ └── values │ ├── arrays.xml │ ├── attrs.xml │ ├── color.xml │ ├── colors.xml │ ├── dimens.xml │ ├── ids.xml │ ├── pull_refresh_strings.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png └── show.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | #built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Windows thumbnail db 19 | Thumbs.db 20 | 21 | # OSX files 22 | .DS_Store 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | 28 | # Android Studio 29 | .idea/workspace.xml 30 | .idea/task.xml 31 | .idea/gradle.xml 32 | .idea/libraries 33 | .idea/li 34 | .gradle 35 | build/ 36 | 37 | # log files 38 | *.log 39 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | GifAssistant -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | Android 5.1.1 Platform 25 | 26 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GifAssistant.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | 早期代码,不再维护。 3 | # GifAssistant 4 | Android练手项目,可以浏览GIF,或从视频中截取一段制作成GIF图片。 5 | 6 | #开发背景 7 | Android没有直接用于显示gif图片的原生控件(webview除外),加之在看视频时有些很有意思的场景经常想制作成gif图片,PC上有很多影音播放软件可以轻松实现这个功能,但手机上的却很少有,所以本着一边做一边学的想法开始了开发。
8 | 基本都是在业余时间制作,而且也在不断完善中,程序还没有完全OK,开始使用eclipse+adt,后来受github影响开始迁移到android studio,现在使用github托管,不断学习进步。 9 | 10 | #程序介绍 11 | 1.第一次使用的引导界面,仿墨迹天气3.0动画
12 | 2.ResideMenu效果
13 | 3.显示Gif图片,GifView
14 | 4.视频播放,图片截取
15 | 5.移植ffmpeg到android,并使用jni进行调用,通过ffmpeg command生成gif
16 | ..具体移植过程可以参考我的另外一个项目[ffmpeg for android shared library](https://github.com/dxjia/ffmpeg-for-android-shared-library)
17 | 6.提供压缩率、帧率以及residemenu背景设置
18 | 7.圆角菜单
19 | 20 | #程序编译 21 | 1.使用git clone下载项目到你的本地;
22 | 2.使用Android Studio - Open an existing Android Studio project,打开clone下来的工程;
23 | 3.build
24 | 25 | #程序截图 26 | ![image](https://github.com/dxjia/GifAssistant/blob/master/screenshot/5.png) 27 | ![image](https://github.com/dxjia/GifAssistant/blob/master/screenshot/6.png) 28 | ![image](https://github.com/dxjia/GifAssistant/blob/master/screenshot/7.png) 29 | ![image](https://github.com/dxjia/GifAssistant/blob/master/screenshot/8.png) 30 | #Reference & Thanks 31 | [ViewPager-Android](https://github.com/rharter/ViewPager-Android)
32 | [mojichina](https://github.com/xyzhang/mojichina)
33 | [AndroidResideMenu](https://github.com/SpecialCyCi/AndroidResideMenu)
34 | [SpringIndicator](https://github.com/chenupt/SpringIndicator)
35 | ...... 36 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | .apk -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | signingConfigs { 5 | } 6 | compileSdkVersion 19 7 | buildToolsVersion '20' 8 | defaultConfig { 9 | applicationId "com.wind.gifassistant" 10 | minSdkVersion 16 11 | targetSdkVersion 19 12 | versionCode 1 13 | versionName "Gif-A 1.0" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | lintOptions { 23 | abortOnError false 24 | } 25 | } 26 | repositories { 27 | flatDir { 28 | dirs 'libs' 29 | } 30 | } 31 | 32 | dependencies { 33 | compile fileTree(include: ['*.jar'], dir: 'libs') 34 | compile files('libs/android-support-v4.jar') 35 | compile files('libs/android-support-v7-appcompat.jar') 36 | compile files('libs/nineoldandroids-library-2.4.0.jar') 37 | compile(name: 'floatingactionbutton-1.9.0', ext: 'aar') 38 | } 39 | -------------------------------------------------------------------------------- /app/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/libs/android-support-v4.jar -------------------------------------------------------------------------------- /app/libs/android-support-v7-appcompat.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/libs/android-support-v7-appcompat.jar -------------------------------------------------------------------------------- /app/libs/floatingactionbutton-1.9.0.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/libs/floatingactionbutton-1.9.0.aar -------------------------------------------------------------------------------- /app/libs/nineoldandroids-library-2.4.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/libs/nineoldandroids-library-2.4.0.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in F:\android\android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/wind/gifassistant/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 23 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 39 | 44 | 45 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/assets/Satisfy-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/assets/Satisfy-Regular.ttf -------------------------------------------------------------------------------- /app/src/main/java/com/chenupt/springindicator/Point.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 chenupt 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.chenupt.springindicator; 18 | 19 | /** 20 | * Created by chenupt@gmail.com on 2015/1/31. 21 | * Description : SpringView point 22 | */ 23 | public class Point { 24 | 25 | private float x; 26 | private float y; 27 | private float radius; 28 | private int color; 29 | 30 | public float getX() { 31 | return x; 32 | } 33 | 34 | public void setX(float x) { 35 | this.x = x; 36 | } 37 | 38 | public float getY() { 39 | return y; 40 | } 41 | 42 | public void setY(float y) { 43 | this.y = y; 44 | } 45 | 46 | public float getRadius() { 47 | return radius; 48 | } 49 | 50 | public void setRadius(float radius) { 51 | this.radius = radius; 52 | } 53 | 54 | public int getColor() { 55 | return color; 56 | } 57 | 58 | public void setColor(int color) { 59 | this.color = color; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/chenupt/springindicator/TabClickListener.java: -------------------------------------------------------------------------------- 1 | package com.chenupt.springindicator; 2 | 3 | /** 4 | * Created by chenupt@gmail.com on 2/28/15. 5 | * Description : Listener for tab 6 | */ 7 | public interface TabClickListener { 8 | 9 | /** 10 | * Handle click event when tab is clicked. 11 | * @param position ViewPager item position. 12 | * @return Call setCurrentItem if return true. 13 | */ 14 | public boolean onTabClick(int position); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/chenupt/springindicator/viewpager/FixedSpeedScroller.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 chenupt 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.chenupt.springindicator.viewpager; 18 | 19 | import android.content.Context; 20 | import android.view.animation.Interpolator; 21 | import android.widget.Scroller; 22 | 23 | public class FixedSpeedScroller extends Scroller { 24 | 25 | private int mDuration = 1000; 26 | boolean useFixedSpeed = false; 27 | 28 | public FixedSpeedScroller(Context context) { 29 | super(context); 30 | } 31 | 32 | public FixedSpeedScroller(Context context, Interpolator interpolator) { 33 | super(context, interpolator); 34 | } 35 | 36 | public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) { 37 | super(context, interpolator, flywheel); 38 | } 39 | 40 | public void setScrollAtFixedSpeed(int paramInt) { 41 | this.useFixedSpeed = true; 42 | this.mDuration = paramInt; 43 | } 44 | 45 | @Override 46 | public void startScroll(int startX, int startY, int dx, int dy, int duration) { 47 | // Ignore received duration, use fixed one instead 48 | super.startScroll(startX, startY, dx, dy, mDuration); 49 | 50 | } 51 | 52 | @Override 53 | public void startScroll(int startX, int startY, int dx, int dy) { 54 | // Ignore received duration, use fixed one instead 55 | super.startScroll(startX, startY, dx, dy, mDuration); 56 | } 57 | 58 | public void setDuration(int timeMilli){ 59 | this.mDuration = timeMilli; 60 | } 61 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chenupt/springindicator/viewpager/ScrollerViewPager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 chenupt 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.chenupt.springindicator.viewpager; 18 | 19 | import android.content.Context; 20 | import android.support.v4.view.ViewPager; 21 | import android.util.AttributeSet; 22 | import android.util.Log; 23 | import android.view.MotionEvent; 24 | import android.view.animation.DecelerateInterpolator; 25 | 26 | import java.lang.reflect.Field; 27 | 28 | /** 29 | * Created by chenupt@gmail.com on 2015/3/7. 30 | * Description TODO 31 | */ 32 | public class ScrollerViewPager extends ViewPager { 33 | 34 | private static final String TAG = ScrollerViewPager.class.getSimpleName(); 35 | 36 | private int duration = 1000; 37 | 38 | public ScrollerViewPager(Context context) { 39 | super(context); 40 | } 41 | 42 | public ScrollerViewPager(Context context, AttributeSet attrs) { 43 | super(context, attrs); 44 | } 45 | 46 | 47 | public void fixScrollSpeed(){ 48 | fixScrollSpeed(duration); 49 | } 50 | 51 | public void fixScrollSpeed(int duration){ 52 | this.duration = duration; 53 | setScrollSpeedUsingRefection(duration); 54 | } 55 | 56 | 57 | private void setScrollSpeedUsingRefection(int duration) { 58 | try { 59 | Field localField = ViewPager.class.getDeclaredField("mScroller"); 60 | localField.setAccessible(true); 61 | FixedSpeedScroller scroller = new FixedSpeedScroller(getContext(), new DecelerateInterpolator(1.5F)); 62 | scroller.setDuration(duration); 63 | localField.set(this, scroller); 64 | return; 65 | } catch (IllegalAccessException localIllegalAccessException) { 66 | } catch (IllegalArgumentException localIllegalArgumentException) { 67 | } catch (NoSuchFieldException localNoSuchFieldException) { 68 | } 69 | } 70 | 71 | @Override 72 | public boolean onInterceptTouchEvent(MotionEvent ev) { 73 | try { 74 | return super.onInterceptTouchEvent(ev); 75 | } catch (IllegalArgumentException e) { 76 | Log.e(TAG, "onInterceptTouchEvent in IllegalArgumentException"); 77 | return false; 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/ILoadingLayout.java: -------------------------------------------------------------------------------- 1 | package com.handmark.pulltorefresh.library; 2 | 3 | import android.graphics.Typeface; 4 | import android.graphics.drawable.Drawable; 5 | 6 | public interface ILoadingLayout { 7 | 8 | /** 9 | * Set the Last Updated Text. This displayed under the main label when 10 | * Pulling 11 | * 12 | * @param label - Label to set 13 | */ 14 | public void setLastUpdatedLabel(CharSequence label); 15 | 16 | /** 17 | * Set the drawable used in the loading layout. This is the same as calling 18 | * setLoadingDrawable(drawable, Mode.BOTH) 19 | * 20 | * @param drawable - Drawable to display 21 | */ 22 | public void setLoadingDrawable(Drawable drawable); 23 | 24 | /** 25 | * Set Text to show when the Widget is being Pulled 26 | * setPullLabel(releaseLabel, Mode.BOTH) 27 | * 28 | * @param pullLabel - CharSequence to display 29 | */ 30 | public void setPullLabel(CharSequence pullLabel); 31 | 32 | /** 33 | * Set Text to show when the Widget is refreshing 34 | * setRefreshingLabel(releaseLabel, Mode.BOTH) 35 | * 36 | * @param refreshingLabel - CharSequence to display 37 | */ 38 | public void setRefreshingLabel(CharSequence refreshingLabel); 39 | 40 | /** 41 | * Set Text to show when the Widget is being pulled, and will refresh when 42 | * released. This is the same as calling 43 | * setReleaseLabel(releaseLabel, Mode.BOTH) 44 | * 45 | * @param releaseLabel - CharSequence to display 46 | */ 47 | public void setReleaseLabel(CharSequence releaseLabel); 48 | 49 | /** 50 | * Set's the Sets the typeface and style in which the text should be 51 | * displayed. Please see 52 | * {@link android.widget.TextView#setTypeface(Typeface) 53 | * TextView#setTypeface(Typeface)}. 54 | */ 55 | public void setTextTypeface(Typeface tf); 56 | 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/LoadingLayoutProxy.java: -------------------------------------------------------------------------------- 1 | package com.handmark.pulltorefresh.library; 2 | 3 | import java.util.HashSet; 4 | 5 | import android.graphics.Typeface; 6 | import android.graphics.drawable.Drawable; 7 | 8 | import com.handmark.pulltorefresh.library.internal.LoadingLayout; 9 | 10 | public class LoadingLayoutProxy implements ILoadingLayout { 11 | 12 | private final HashSet mLoadingLayouts; 13 | 14 | LoadingLayoutProxy() { 15 | mLoadingLayouts = new HashSet(); 16 | } 17 | 18 | /** 19 | * This allows you to add extra LoadingLayout instances to this proxy. This 20 | * is only necessary if you keep your own instances, and want to have them 21 | * included in any 22 | * {@link PullToRefreshBase#createLoadingLayoutProxy(boolean, boolean) 23 | * createLoadingLayoutProxy(...)} calls. 24 | * 25 | * @param layout - LoadingLayout to have included. 26 | */ 27 | public void addLayout(LoadingLayout layout) { 28 | if (null != layout) { 29 | mLoadingLayouts.add(layout); 30 | } 31 | } 32 | 33 | @Override 34 | public void setLastUpdatedLabel(CharSequence label) { 35 | for (LoadingLayout layout : mLoadingLayouts) { 36 | layout.setLastUpdatedLabel(label); 37 | } 38 | } 39 | 40 | @Override 41 | public void setLoadingDrawable(Drawable drawable) { 42 | for (LoadingLayout layout : mLoadingLayouts) { 43 | layout.setLoadingDrawable(drawable); 44 | } 45 | } 46 | 47 | @Override 48 | public void setRefreshingLabel(CharSequence refreshingLabel) { 49 | for (LoadingLayout layout : mLoadingLayouts) { 50 | layout.setRefreshingLabel(refreshingLabel); 51 | } 52 | } 53 | 54 | @Override 55 | public void setPullLabel(CharSequence label) { 56 | for (LoadingLayout layout : mLoadingLayouts) { 57 | layout.setPullLabel(label); 58 | } 59 | } 60 | 61 | @Override 62 | public void setReleaseLabel(CharSequence label) { 63 | for (LoadingLayout layout : mLoadingLayouts) { 64 | layout.setReleaseLabel(label); 65 | } 66 | } 67 | 68 | public void setTextTypeface(Typeface tf) { 69 | for (LoadingLayout layout : mLoadingLayouts) { 70 | layout.setTextTypeface(tf); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshExpandableListView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library; 17 | 18 | import android.annotation.TargetApi; 19 | import android.content.Context; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.util.AttributeSet; 23 | import android.view.View; 24 | import android.widget.ExpandableListView; 25 | 26 | import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor; 27 | 28 | public class PullToRefreshExpandableListView extends PullToRefreshAdapterViewBase { 29 | 30 | public PullToRefreshExpandableListView(Context context) { 31 | super(context); 32 | } 33 | 34 | public PullToRefreshExpandableListView(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | } 37 | 38 | public PullToRefreshExpandableListView(Context context, Mode mode) { 39 | super(context, mode); 40 | } 41 | 42 | public PullToRefreshExpandableListView(Context context, Mode mode, AnimationStyle style) { 43 | super(context, mode, style); 44 | } 45 | 46 | @Override 47 | public final Orientation getPullToRefreshScrollDirection() { 48 | return Orientation.VERTICAL; 49 | } 50 | 51 | @Override 52 | protected ExpandableListView createRefreshableView(Context context, AttributeSet attrs) { 53 | final ExpandableListView lv; 54 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 55 | lv = new InternalExpandableListViewSDK9(context, attrs); 56 | } else { 57 | lv = new InternalExpandableListView(context, attrs); 58 | } 59 | 60 | // Set it to this so it can be used in ListActivity/ListFragment 61 | lv.setId(android.R.id.list); 62 | return lv; 63 | } 64 | 65 | class InternalExpandableListView extends ExpandableListView implements EmptyViewMethodAccessor { 66 | 67 | public InternalExpandableListView(Context context, AttributeSet attrs) { 68 | super(context, attrs); 69 | } 70 | 71 | @Override 72 | public void setEmptyView(View emptyView) { 73 | PullToRefreshExpandableListView.this.setEmptyView(emptyView); 74 | } 75 | 76 | @Override 77 | public void setEmptyViewInternal(View emptyView) { 78 | super.setEmptyView(emptyView); 79 | } 80 | } 81 | 82 | @TargetApi(9) 83 | final class InternalExpandableListViewSDK9 extends InternalExpandableListView { 84 | 85 | public InternalExpandableListViewSDK9(Context context, AttributeSet attrs) { 86 | super(context, attrs); 87 | } 88 | 89 | @Override 90 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, 91 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { 92 | 93 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, 94 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 95 | 96 | // Does all of the hard work... 97 | OverscrollHelper.overScrollBy(PullToRefreshExpandableListView.this, deltaX, scrollX, deltaY, scrollY, 98 | isTouchEvent); 99 | 100 | return returnValue; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshGridView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library; 17 | 18 | import android.annotation.TargetApi; 19 | import android.content.Context; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.util.AttributeSet; 23 | import android.view.View; 24 | import android.widget.GridView; 25 | 26 | import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor; 27 | 28 | import com.wind.gifassistant.R; 29 | 30 | public class PullToRefreshGridView extends PullToRefreshAdapterViewBase { 31 | 32 | public PullToRefreshGridView(Context context) { 33 | super(context); 34 | } 35 | 36 | public PullToRefreshGridView(Context context, AttributeSet attrs) { 37 | super(context, attrs); 38 | } 39 | 40 | public PullToRefreshGridView(Context context, Mode mode) { 41 | super(context, mode); 42 | } 43 | 44 | public PullToRefreshGridView(Context context, Mode mode, AnimationStyle style) { 45 | super(context, mode, style); 46 | } 47 | 48 | @Override 49 | public final Orientation getPullToRefreshScrollDirection() { 50 | return Orientation.VERTICAL; 51 | } 52 | 53 | @Override 54 | protected final GridView createRefreshableView(Context context, AttributeSet attrs) { 55 | final GridView gv; 56 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 57 | gv = new InternalGridViewSDK9(context, attrs); 58 | } else { 59 | gv = new InternalGridView(context, attrs); 60 | } 61 | 62 | // Use Generated ID (from res/values/ids.xml) 63 | gv.setId(R.id.gridview); 64 | return gv; 65 | } 66 | 67 | class InternalGridView extends GridView implements EmptyViewMethodAccessor { 68 | 69 | public InternalGridView(Context context, AttributeSet attrs) { 70 | super(context, attrs); 71 | } 72 | 73 | @Override 74 | public void setEmptyView(View emptyView) { 75 | PullToRefreshGridView.this.setEmptyView(emptyView); 76 | } 77 | 78 | @Override 79 | public void setEmptyViewInternal(View emptyView) { 80 | super.setEmptyView(emptyView); 81 | } 82 | } 83 | 84 | @TargetApi(9) 85 | final class InternalGridViewSDK9 extends InternalGridView { 86 | 87 | public InternalGridViewSDK9(Context context, AttributeSet attrs) { 88 | super(context, attrs); 89 | } 90 | 91 | @Override 92 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, 93 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { 94 | 95 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, 96 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 97 | 98 | // Does all of the hard work... 99 | OverscrollHelper.overScrollBy(PullToRefreshGridView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent); 100 | 101 | return returnValue; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshHorizontalScrollView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library; 17 | 18 | import android.annotation.TargetApi; 19 | import android.content.Context; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.util.AttributeSet; 23 | import android.view.View; 24 | import android.widget.HorizontalScrollView; 25 | 26 | import com.wind.gifassistant.R; 27 | 28 | public class PullToRefreshHorizontalScrollView extends PullToRefreshBase { 29 | 30 | public PullToRefreshHorizontalScrollView(Context context) { 31 | super(context); 32 | } 33 | 34 | public PullToRefreshHorizontalScrollView(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | } 37 | 38 | public PullToRefreshHorizontalScrollView(Context context, Mode mode) { 39 | super(context, mode); 40 | } 41 | 42 | public PullToRefreshHorizontalScrollView(Context context, Mode mode, AnimationStyle style) { 43 | super(context, mode, style); 44 | } 45 | 46 | @Override 47 | public final Orientation getPullToRefreshScrollDirection() { 48 | return Orientation.HORIZONTAL; 49 | } 50 | 51 | @Override 52 | protected HorizontalScrollView createRefreshableView(Context context, AttributeSet attrs) { 53 | HorizontalScrollView scrollView; 54 | 55 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 56 | scrollView = new InternalHorizontalScrollViewSDK9(context, attrs); 57 | } else { 58 | scrollView = new HorizontalScrollView(context, attrs); 59 | } 60 | 61 | scrollView.setId(R.id.scrollview); 62 | return scrollView; 63 | } 64 | 65 | @Override 66 | protected boolean isReadyForPullStart() { 67 | return mRefreshableView.getScrollX() == 0; 68 | } 69 | 70 | @Override 71 | protected boolean isReadyForPullEnd() { 72 | View scrollViewChild = mRefreshableView.getChildAt(0); 73 | if (null != scrollViewChild) { 74 | return mRefreshableView.getScrollX() >= (scrollViewChild.getWidth() - getWidth()); 75 | } 76 | return false; 77 | } 78 | 79 | @TargetApi(9) 80 | final class InternalHorizontalScrollViewSDK9 extends HorizontalScrollView { 81 | 82 | public InternalHorizontalScrollViewSDK9(Context context, AttributeSet attrs) { 83 | super(context, attrs); 84 | } 85 | 86 | @Override 87 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, 88 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { 89 | 90 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, 91 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 92 | 93 | // Does all of the hard work... 94 | OverscrollHelper.overScrollBy(PullToRefreshHorizontalScrollView.this, deltaX, scrollX, deltaY, scrollY, 95 | getScrollRange(), isTouchEvent); 96 | 97 | return returnValue; 98 | } 99 | 100 | /** 101 | * Taken from the AOSP ScrollView source 102 | */ 103 | private int getScrollRange() { 104 | int scrollRange = 0; 105 | if (getChildCount() > 0) { 106 | View child = getChildAt(0); 107 | scrollRange = Math.max(0, child.getWidth() - (getWidth() - getPaddingLeft() - getPaddingRight())); 108 | } 109 | return scrollRange; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshScrollView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library; 17 | 18 | import android.annotation.TargetApi; 19 | import android.content.Context; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.util.AttributeSet; 23 | import android.view.View; 24 | import android.widget.ScrollView; 25 | 26 | import com.wind.gifassistant.R; 27 | 28 | public class PullToRefreshScrollView extends PullToRefreshBase { 29 | 30 | public PullToRefreshScrollView(Context context) { 31 | super(context); 32 | } 33 | 34 | public PullToRefreshScrollView(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | } 37 | 38 | public PullToRefreshScrollView(Context context, Mode mode) { 39 | super(context, mode); 40 | } 41 | 42 | public PullToRefreshScrollView(Context context, Mode mode, AnimationStyle style) { 43 | super(context, mode, style); 44 | } 45 | 46 | @Override 47 | public final Orientation getPullToRefreshScrollDirection() { 48 | return Orientation.VERTICAL; 49 | } 50 | 51 | @Override 52 | protected ScrollView createRefreshableView(Context context, AttributeSet attrs) { 53 | ScrollView scrollView; 54 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 55 | scrollView = new InternalScrollViewSDK9(context, attrs); 56 | } else { 57 | scrollView = new ScrollView(context, attrs); 58 | } 59 | 60 | scrollView.setId(R.id.scrollview); 61 | return scrollView; 62 | } 63 | 64 | @Override 65 | protected boolean isReadyForPullStart() { 66 | return mRefreshableView.getScrollY() == 0; 67 | } 68 | 69 | @Override 70 | protected boolean isReadyForPullEnd() { 71 | View scrollViewChild = mRefreshableView.getChildAt(0); 72 | if (null != scrollViewChild) { 73 | return mRefreshableView.getScrollY() >= (scrollViewChild.getHeight() - getHeight()); 74 | } 75 | return false; 76 | } 77 | 78 | @TargetApi(9) 79 | final class InternalScrollViewSDK9 extends ScrollView { 80 | 81 | public InternalScrollViewSDK9(Context context, AttributeSet attrs) { 82 | super(context, attrs); 83 | } 84 | 85 | @Override 86 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, 87 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { 88 | 89 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, 90 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 91 | 92 | // Does all of the hard work... 93 | OverscrollHelper.overScrollBy(PullToRefreshScrollView.this, deltaX, scrollX, deltaY, scrollY, 94 | getScrollRange(), isTouchEvent); 95 | 96 | return returnValue; 97 | } 98 | 99 | /** 100 | * Taken from the AOSP ScrollView source 101 | */ 102 | private int getScrollRange() { 103 | int scrollRange = 0; 104 | if (getChildCount() > 0) { 105 | View child = getChildAt(0); 106 | scrollRange = Math.max(0, child.getHeight() - (getHeight() - getPaddingBottom() - getPaddingTop())); 107 | } 108 | return scrollRange; 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/extras/SoundPullEventListener.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.extras; 17 | 18 | import java.util.HashMap; 19 | 20 | import android.content.Context; 21 | import android.media.MediaPlayer; 22 | import android.view.View; 23 | 24 | import com.handmark.pulltorefresh.library.PullToRefreshBase; 25 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; 26 | import com.handmark.pulltorefresh.library.PullToRefreshBase.State; 27 | 28 | public class SoundPullEventListener implements PullToRefreshBase.OnPullEventListener { 29 | 30 | private final Context mContext; 31 | private final HashMap mSoundMap; 32 | 33 | private MediaPlayer mCurrentMediaPlayer; 34 | 35 | /** 36 | * Constructor 37 | * 38 | * @param context - Context 39 | */ 40 | public SoundPullEventListener(Context context) { 41 | mContext = context; 42 | mSoundMap = new HashMap(); 43 | } 44 | 45 | @Override 46 | public final void onPullEvent(PullToRefreshBase refreshView, State event, Mode direction) { 47 | Integer soundResIdObj = mSoundMap.get(event); 48 | if (null != soundResIdObj) { 49 | playSound(soundResIdObj.intValue()); 50 | } 51 | } 52 | 53 | /** 54 | * Set the Sounds to be played when a Pull Event happens. You specify which 55 | * sound plays for which events by calling this method multiple times for 56 | * each event. 57 | *

58 | * If you've already set a sound for a certain event, and add another sound 59 | * for that event, only the new sound will be played. 60 | * 61 | * @param event - The event for which the sound will be played. 62 | * @param resId - Resource Id of the sound file to be played (e.g. 63 | * R.raw.pull_sound) 64 | */ 65 | public void addSoundEvent(State event, int resId) { 66 | mSoundMap.put(event, resId); 67 | } 68 | 69 | /** 70 | * Clears all of the previously set sounds and events. 71 | */ 72 | public void clearSounds() { 73 | mSoundMap.clear(); 74 | } 75 | 76 | /** 77 | * Gets the current (or last) MediaPlayer instance. 78 | */ 79 | public MediaPlayer getCurrentMediaPlayer() { 80 | return mCurrentMediaPlayer; 81 | } 82 | 83 | private void playSound(int resId) { 84 | // Stop current player, if there's one playing 85 | if (null != mCurrentMediaPlayer) { 86 | mCurrentMediaPlayer.stop(); 87 | mCurrentMediaPlayer.release(); 88 | } 89 | 90 | mCurrentMediaPlayer = MediaPlayer.create(mContext, resId); 91 | if (null != mCurrentMediaPlayer) { 92 | mCurrentMediaPlayer.start(); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/internal/EmptyViewMethodAccessor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.internal; 17 | 18 | import android.view.View; 19 | 20 | /** 21 | * Interface that allows PullToRefreshBase to hijack the call to 22 | * AdapterView.setEmptyView() 23 | * 24 | * @author chris 25 | */ 26 | public interface EmptyViewMethodAccessor { 27 | 28 | /** 29 | * Calls upto AdapterView.setEmptyView() 30 | * 31 | * @param emptyView - to set as Empty View 32 | */ 33 | public void setEmptyViewInternal(View emptyView); 34 | 35 | /** 36 | * Should call PullToRefreshBase.setEmptyView() which will then 37 | * automatically call through to setEmptyViewInternal() 38 | * 39 | * @param emptyView - to set as Empty View 40 | */ 41 | public void setEmptyView(View emptyView); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/internal/RotateLoadingLayout.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.internal; 17 | 18 | import android.content.Context; 19 | import android.content.res.TypedArray; 20 | import android.graphics.Matrix; 21 | import android.graphics.drawable.Drawable; 22 | import android.view.animation.Animation; 23 | import android.view.animation.RotateAnimation; 24 | import android.widget.ImageView.ScaleType; 25 | 26 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; 27 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation; 28 | import com.wind.gifassistant.R; 29 | 30 | public class RotateLoadingLayout extends LoadingLayout { 31 | 32 | static final int ROTATION_ANIMATION_DURATION = 1200; 33 | 34 | private final Animation mRotateAnimation; 35 | private final Matrix mHeaderImageMatrix; 36 | 37 | private float mRotationPivotX, mRotationPivotY; 38 | 39 | private final boolean mRotateDrawableWhilePulling; 40 | 41 | public RotateLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) { 42 | super(context, mode, scrollDirection, attrs); 43 | 44 | mRotateDrawableWhilePulling = attrs.getBoolean(R.styleable.PullToRefresh_ptrRotateDrawableWhilePulling, true); 45 | 46 | mHeaderImage.setScaleType(ScaleType.MATRIX); 47 | mHeaderImageMatrix = new Matrix(); 48 | mHeaderImage.setImageMatrix(mHeaderImageMatrix); 49 | 50 | mRotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 51 | 0.5f); 52 | mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR); 53 | mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION); 54 | mRotateAnimation.setRepeatCount(Animation.INFINITE); 55 | mRotateAnimation.setRepeatMode(Animation.RESTART); 56 | } 57 | 58 | public void onLoadingDrawableSet(Drawable imageDrawable) { 59 | if (null != imageDrawable) { 60 | mRotationPivotX = Math.round(imageDrawable.getIntrinsicWidth() / 2f); 61 | mRotationPivotY = Math.round(imageDrawable.getIntrinsicHeight() / 2f); 62 | } 63 | } 64 | 65 | protected void onPullImpl(float scaleOfLayout) { 66 | float angle; 67 | if (mRotateDrawableWhilePulling) { 68 | angle = scaleOfLayout * 90f; 69 | } else { 70 | angle = Math.max(0f, Math.min(180f, scaleOfLayout * 360f - 180f)); 71 | } 72 | 73 | mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY); 74 | mHeaderImage.setImageMatrix(mHeaderImageMatrix); 75 | } 76 | 77 | @Override 78 | protected void refreshingImpl() { 79 | mHeaderImage.startAnimation(mRotateAnimation); 80 | } 81 | 82 | @Override 83 | protected void resetImpl() { 84 | mHeaderImage.clearAnimation(); 85 | resetImageRotation(); 86 | } 87 | 88 | private void resetImageRotation() { 89 | if (null != mHeaderImageMatrix) { 90 | mHeaderImageMatrix.reset(); 91 | mHeaderImage.setImageMatrix(mHeaderImageMatrix); 92 | } 93 | } 94 | 95 | @Override 96 | protected void pullToRefreshImpl() { 97 | // NO-OP 98 | } 99 | 100 | @Override 101 | protected void releaseToRefreshImpl() { 102 | // NO-OP 103 | } 104 | 105 | @Override 106 | protected int getDefaultDrawableResId() { 107 | return R.mipmap.default_ptr_rotate; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/internal/Utils.java: -------------------------------------------------------------------------------- 1 | package com.handmark.pulltorefresh.library.internal; 2 | 3 | import android.util.Log; 4 | 5 | public class Utils { 6 | 7 | static final String LOG_TAG = "PullToRefresh"; 8 | 9 | public static void warnDeprecation(String depreacted, String replacement) { 10 | Log.w(LOG_TAG, "You're using the deprecated " + depreacted + " attr, please switch over to " + replacement); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/handmark/pulltorefresh/library/internal/ViewCompat.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.internal; 17 | 18 | import android.annotation.TargetApi; 19 | import android.graphics.drawable.Drawable; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.view.View; 23 | 24 | @SuppressWarnings("deprecation") 25 | public class ViewCompat { 26 | 27 | public static void postOnAnimation(View view, Runnable runnable) { 28 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { 29 | SDK16.postOnAnimation(view, runnable); 30 | } else { 31 | view.postDelayed(runnable, 16); 32 | } 33 | } 34 | 35 | public static void setBackground(View view, Drawable background) { 36 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { 37 | SDK16.setBackground(view, background); 38 | } else { 39 | view.setBackgroundDrawable(background); 40 | } 41 | } 42 | 43 | public static void setLayerType(View view, int layerType) { 44 | if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 45 | SDK11.setLayerType(view, layerType); 46 | } 47 | } 48 | 49 | @TargetApi(11) 50 | static class SDK11 { 51 | 52 | public static void setLayerType(View view, int layerType) { 53 | view.setLayerType(layerType, null); 54 | } 55 | } 56 | 57 | @TargetApi(16) 58 | static class SDK16 { 59 | 60 | public static void postOnAnimation(View view, Runnable runnable) { 61 | view.postOnAnimation(runnable); 62 | } 63 | 64 | public static void setBackground(View view, Drawable background) { 65 | view.setBackground(background); 66 | } 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/ryanharter/viewpager/PagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.ryanharter.viewpager; 2 | 3 | /** 4 | * {@inheritDoc} 5 | */ 6 | public abstract class PagerAdapter extends android.support.v4.view.PagerAdapter { 7 | 8 | /** 9 | * {@inheritDoc} 10 | * @deprecated Use {@link #getPageSize(int)} instead. 11 | */ 12 | @Override 13 | public float getPageWidth(int position) { 14 | return super.getPageWidth(position); 15 | } 16 | 17 | /** 18 | * Returns the proportional size (width or height depending on orientation) 19 | * of a given page as a percentage of the ViewPager's measured size from (0.f-1.f). 20 | * 21 | * @param position The position of the page requested 22 | * @return Proportional size for the given page position 23 | */ 24 | public float getPageSize(int position) { 25 | return getPageWidth(position); 26 | } 27 | 28 | public CharSequence getPageTitle(int position) { 29 | return (position +1)+""; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/special/ResideMenu/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 SpecialCyCi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/special/ResideMenu/ResideMenuItem.java: -------------------------------------------------------------------------------- 1 | package com.special.ResideMenu; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.widget.ImageView; 6 | import android.widget.LinearLayout; 7 | import android.widget.TextView; 8 | 9 | import com.wind.gifassistant.R; 10 | 11 | /** 12 | * User: special 13 | * Date: 13-12-10 14 | * Time: 下午11:05 15 | * Mail: specialcyci@gmail.com 16 | */ 17 | public class ResideMenuItem extends LinearLayout{ 18 | 19 | /** menu item icon */ 20 | private ImageView iv_icon; 21 | /** menu item title */ 22 | private TextView tv_title; 23 | 24 | public ResideMenuItem(Context context) { 25 | super(context); 26 | initViews(context); 27 | } 28 | 29 | public ResideMenuItem(Context context, int icon, int title) { 30 | super(context); 31 | initViews(context); 32 | iv_icon.setImageResource(icon); 33 | tv_title.setText(title); 34 | setTitleColorSelector(R.drawable.reside_menu_text_selector); 35 | } 36 | 37 | public ResideMenuItem(Context context, int icon, String title) { 38 | super(context); 39 | initViews(context); 40 | iv_icon.setImageResource(icon); 41 | tv_title.setText(title); 42 | setTitleColorSelector(R.drawable.reside_menu_text_selector); 43 | } 44 | 45 | private void initViews(Context context){ 46 | LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 47 | inflater.inflate(R.layout.residemenu_item, this); 48 | iv_icon = (ImageView) findViewById(R.id.iv_icon); 49 | tv_title = (TextView) findViewById(R.id.tv_title); 50 | } 51 | 52 | /** 53 | * set the icon color; 54 | * 55 | * @param icon 56 | */ 57 | public void setIcon(int icon){ 58 | iv_icon.setImageResource(icon); 59 | } 60 | 61 | /** 62 | * set the title with resource 63 | * ; 64 | * @param title 65 | */ 66 | public void setTitle(int title){ 67 | tv_title.setText(title); 68 | } 69 | 70 | /** 71 | * set the title with string; 72 | * 73 | * @param title 74 | */ 75 | public void setTitle(String title){ 76 | tv_title.setText(title); 77 | } 78 | 79 | /** 80 | * set the title color selector 81 | * 82 | * @param resid 83 | */ 84 | public void setTitleColorSelector(int resid) { 85 | //tv_title.setTextColor(resid); 86 | //tv_title.setOnClickListener(null); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/special/ResideMenu/TouchDisableView.java: -------------------------------------------------------------------------------- 1 | package com.special.ResideMenu; 2 | 3 | 4 | 5 | import android.content.Context; 6 | import android.util.AttributeSet; 7 | import android.view.MotionEvent; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | /** 12 | * Created by thonguyen on 15/4/14. 13 | */ 14 | class TouchDisableView extends ViewGroup { 15 | 16 | private View mContent; 17 | 18 | // private int mMode; 19 | private boolean mTouchDisabled = false; 20 | 21 | public TouchDisableView(Context context) { 22 | this(context, null); 23 | } 24 | 25 | public TouchDisableView(Context context, AttributeSet attrs) { 26 | super(context, attrs); 27 | } 28 | 29 | public void setContent(View v) { 30 | if (mContent != null) { 31 | this.removeView(mContent); 32 | } 33 | mContent = v; 34 | addView(mContent); 35 | } 36 | 37 | public View getContent() { 38 | return mContent; 39 | } 40 | 41 | @Override 42 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 43 | 44 | int width = getDefaultSize(0, widthMeasureSpec); 45 | int height = getDefaultSize(0, heightMeasureSpec); 46 | setMeasuredDimension(width, height); 47 | 48 | final int contentWidth = getChildMeasureSpec(widthMeasureSpec, 0, width); 49 | final int contentHeight = getChildMeasureSpec(heightMeasureSpec, 0, height); 50 | mContent.measure(contentWidth, contentHeight); 51 | } 52 | 53 | @Override 54 | protected void onLayout(boolean changed, int l, int t, int r, int b) { 55 | final int width = r - l; 56 | final int height = b - t; 57 | mContent.layout(0, 0, width, height); 58 | } 59 | 60 | @Override 61 | public boolean onInterceptTouchEvent(MotionEvent ev) { 62 | return mTouchDisabled; 63 | } 64 | 65 | void setTouchDisable(boolean disableTouch) { 66 | mTouchDisabled = disableTouch; 67 | } 68 | 69 | boolean isTouchDisabled() { 70 | return mTouchDisabled; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/ffmpeghelper/FFmpegCommandBuilder.java: -------------------------------------------------------------------------------- 1 | package com.wind.ffmpeghelper; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * Created by 德祥 on 2015/4/28. 7 | */ 8 | public class FFmpegCommandBuilder { 9 | 10 | private final static String FFMPEG_TAG = "ffmpeg"; 11 | private final static String COMMAND_SPACE = " "; 12 | 13 | private ArrayList mParameterList; 14 | 15 | public FFmpegCommandBuilder() { 16 | mParameterList = new ArrayList(); 17 | mParameterList.add(FFMPEG_TAG); 18 | } 19 | 20 | public void append(String parameter) { 21 | mParameterList.add(parameter); 22 | } 23 | 24 | public void append(int parameter) { 25 | mParameterList.add(String.valueOf(parameter)); 26 | } 27 | 28 | public String getCommand() { 29 | StringBuilder sb = new StringBuilder(); 30 | int i = 0; 31 | for (; i < (mParameterList.size() - 1); i++) { 32 | sb.append(mParameterList.get(i)); 33 | sb.append(COMMAND_SPACE); 34 | } 35 | 36 | sb.append(mParameterList.get(i)); 37 | 38 | return sb.toString(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/ffmpeghelper/FFmpegNativeHelper.java: -------------------------------------------------------------------------------- 1 | package com.wind.ffmpeghelper; 2 | 3 | /** 4 | * Created by 德祥 on 2015/4/28. 5 | */ 6 | 7 | import android.util.Log; 8 | 9 | public class FFmpegNativeHelper { 10 | public FFmpegNativeHelper() { 11 | } 12 | 13 | static { 14 | System.loadLibrary("avutil-54"); 15 | System.loadLibrary("swresample-1"); 16 | System.loadLibrary("avcodec-56"); 17 | System.loadLibrary("avformat-56"); 18 | System.loadLibrary("swscale-3"); 19 | System.loadLibrary("avfilter-5"); 20 | System.loadLibrary("avdevice-56"); 21 | System.loadLibrary("ffmpegjni"); 22 | } 23 | 24 | // success 0, error 1 25 | public int ffmpegRunCommand(String command) { 26 | if(command == null || command.length() == 0) { 27 | return 1; 28 | } 29 | String[] args = command.split(" "); 30 | for(int i = 0; i < args.length; i++) { 31 | Log.d("ffmpeg-jni", args[i]); 32 | 33 | } 34 | return ffmpeg_entry(args.length, args); 35 | } 36 | 37 | // argc maybe dont be needed 38 | public native int ffmpeg_entry(int argc, String[] args); 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/GifAssistantApp.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant; 2 | 3 | import com.wind.gifassistant.utils.AppCrashHandler; 4 | 5 | import android.app.Application; 6 | 7 | public class GifAssistantApp extends Application { 8 | @Override 9 | public void onCreate() { 10 | super.onCreate(); 11 | AppCrashHandler crashHandler = AppCrashHandler.getInstance(); 12 | //crashHandler.init(getApplicationContext()); 13 | } 14 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/data/GifProductInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Djia 3 | * All right reserved. 4 | * 5 | * Created on 2014-8-11 6 | */ 7 | package com.wind.gifassistant.data; 8 | 9 | import java.io.File; 10 | import java.io.FileInputStream; 11 | import java.text.DateFormat; 12 | import java.text.DecimalFormat; 13 | import java.text.SimpleDateFormat; 14 | import java.util.Date; 15 | 16 | /** 17 | * 18 | * @author Djia 19 | * @time 2014-8-11上午10:57:08 20 | * @instuction 21 | */ 22 | public class GifProductInfo { 23 | private String mGifName; 24 | private String mGifPath; 25 | private String mLastModifyTime; 26 | private String mFileSize; 27 | 28 | public GifProductInfo(String gifPath) { 29 | // TODO Auto-generated constructor stub 30 | parseFromPath(gifPath); 31 | mGifPath = gifPath; 32 | } 33 | 34 | public String getName() { 35 | return mGifName; 36 | } 37 | 38 | public String getPath() { 39 | return mGifPath; 40 | } 41 | 42 | public String getLastModifyTime() { 43 | return mLastModifyTime; 44 | } 45 | 46 | public String getFileSize() { 47 | return mFileSize; 48 | } 49 | 50 | private void parseFromPath(String gifPath) { 51 | File f = new File(gifPath); 52 | String name = f.getName(); 53 | int length = name.length(); 54 | mGifName = f.getName().substring(0, length - 4); 55 | DateFormat formatter = new SimpleDateFormat("yyyyMMdd-HH:mm:ss"); 56 | Date date = new Date(f.lastModified()); 57 | mLastModifyTime = formatter.format(date); 58 | mFileSize = FormetFileSize(f.length()); 59 | } 60 | 61 | private String FormetFileSize(long filesize) { 62 | DecimalFormat df = new DecimalFormat("#.00"); 63 | String fileSizeString = ""; 64 | if (filesize < 1024) { 65 | fileSizeString = df.format((double) filesize) + "B"; 66 | } else if (filesize < 1048576) { 67 | fileSizeString = df.format((double) filesize / 1024) + "K"; 68 | } else if (filesize < 1073741824) { 69 | fileSizeString = df.format((double) filesize / 1048576) + "M"; 70 | } else { 71 | fileSizeString = df.format((double) filesize / 1073741824) + "G"; 72 | } 73 | return fileSizeString; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/data/VideosFilesScanTask.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Djia 3 | * All right reserved. 4 | * 5 | * Created on 2014-8-7 6 | */ 7 | package com.wind.gifassistant.data; 8 | 9 | import android.content.Context; 10 | import android.os.AsyncTask; 11 | import android.view.View; 12 | import android.widget.BaseAdapter; 13 | import android.widget.ListAdapter; 14 | import android.widget.TextView; 15 | 16 | import com.handmark.pulltorefresh.library.PullToRefreshListView; 17 | import com.wind.gifassistant.utils.AppUtils; 18 | 19 | import java.io.File; 20 | import java.io.FileFilter; 21 | import java.util.ArrayList; 22 | 23 | /** 24 | * 25 | * @author Djia 26 | * @time 2014-8-7上午10:00:03 27 | * @instuction 28 | */ 29 | public class VideosFilesScanTask extends AsyncTask> { 30 | 31 | final Context mContext; 32 | final private ArrayList mListItem; 33 | final private PullToRefreshListView mPullRefreshListView; 34 | final private ListAdapter mAdapter; 35 | final private TextView mEmptyNoteTextView; 36 | 37 | public VideosFilesScanTask(Context context, ArrayList listItem, TextView emptyNoteView, 38 | PullToRefreshListView pullRefreshListView, ListAdapter adapter) { 39 | mContext = context; 40 | mListItem = listItem; 41 | mPullRefreshListView = pullRefreshListView; 42 | mAdapter = adapter; 43 | mEmptyNoteTextView = emptyNoteView; 44 | } 45 | 46 | /* (non-Javadoc) 47 | * @see android.os.AsyncTask#doInBackground(Params[]) 48 | */ 49 | @Override 50 | protected ArrayList doInBackground(Void... params) { 51 | // Simulates a background job. 52 | try { 53 | Thread.sleep(1000); 54 | } catch (InterruptedException e) { 55 | } 56 | 57 | ArrayList result = new ArrayList(); 58 | try { 59 | getVideoFiles(result, new File(AppUtils.VIDEOS_FOLDER_PATH)); 60 | } catch (Exception e) { 61 | // TODO: handle exception 62 | return null; 63 | } 64 | return result; 65 | } 66 | 67 | @Override 68 | protected void onPostExecute(ArrayList result) { 69 | mListItem.clear(); 70 | if (result != null && result.size() > 0 ) { 71 | mListItem.addAll(result); 72 | } 73 | 74 | //通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合 75 | ((BaseAdapter) mAdapter).notifyDataSetChanged(); 76 | // Call onRefreshComplete when the list has been refreshed. 77 | mPullRefreshListView.onRefreshComplete(); 78 | if (mEmptyNoteTextView != null) { 79 | if (mListItem.size() > 0) { 80 | mEmptyNoteTextView.setVisibility(View.GONE); 81 | } else { 82 | mEmptyNoteTextView.setVisibility(View.GONE); 83 | mEmptyNoteTextView.setText("下拉进行刷新"); 84 | } 85 | } 86 | 87 | super.onPostExecute(result); 88 | } 89 | 90 | private void getVideoFiles(final ArrayList list,File file){ 91 | file.listFiles(new FileFilter(){ 92 | @Override 93 | public boolean accept(File file) { 94 | // TODO Auto-generated method stub 95 | if (file != null && file.length() <= 0) { 96 | return false; 97 | } 98 | String name = file.getName(); 99 | int i = name.indexOf('.'); 100 | if(i != -1){ 101 | name = name.substring(i); 102 | if(name.equalsIgnoreCase(".mp4") || name.equalsIgnoreCase(".3gp")){ 103 | list.add(file.getAbsolutePath()); 104 | return true; 105 | } 106 | }else if(file.isDirectory()){ 107 | getVideoFiles(list, file); 108 | } 109 | return false; 110 | } 111 | }); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/data/VideosInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Djia 3 | * All right reserved. 4 | * 5 | * Created on 2014-8-14 6 | */ 7 | package com.wind.gifassistant.data; 8 | 9 | import java.io.File; 10 | import java.text.DateFormat; 11 | import java.text.DecimalFormat; 12 | import java.text.SimpleDateFormat; 13 | import java.util.Date; 14 | 15 | import android.media.MediaMetadataRetriever; 16 | 17 | /** 18 | * 19 | * @author Djia 20 | * @time 2014-8-14下午2:14:57 21 | * @instuction 22 | */ 23 | public class VideosInfo { 24 | private String mName; 25 | private String mLastModifyTime; 26 | private String mDuration; 27 | private String mPath; 28 | 29 | /** 30 | * 31 | */ 32 | public VideosInfo(String path) { 33 | // TODO Auto-generated constructor stub 34 | parseFromPath(path); 35 | mPath = path; 36 | } 37 | 38 | 39 | public String getName() { 40 | return mName; 41 | } 42 | 43 | public String getPath() { 44 | return mPath; 45 | } 46 | 47 | public String getLastModifyTime() { 48 | return mLastModifyTime; 49 | } 50 | 51 | public String getDuration() { 52 | return mDuration; 53 | } 54 | 55 | private void parseFromPath(String path) { 56 | File f = new File(path); 57 | String name = f.getName(); 58 | int length = name.length(); 59 | mName = f.getName().substring(0, length - 4); 60 | DateFormat formatter = new SimpleDateFormat("yyyyMMdd-HH:mm:ss"); 61 | Date date = new Date(f.lastModified()); 62 | mLastModifyTime = formatter.format(date); 63 | mDuration = formatFileDuration(path); 64 | } 65 | 66 | private String formatFileDuration(String path) { 67 | MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 68 | retriever.setDataSource(path); 69 | // 取得视频的长度(单位为毫秒) 70 | String time = retriever 71 | .extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); 72 | // 取得视频的长度(单位为秒) 73 | int totalS = Integer.valueOf(time) / 1000; 74 | 75 | DecimalFormat df = new DecimalFormat("#.00"); 76 | String totalDuration = ""; 77 | if (totalS < 60) { 78 | totalDuration = df.format((double) totalS) + "秒"; 79 | } else if (totalS < 3600) { 80 | totalDuration = df.format((double) totalS / 60) + "分"; 81 | } else if (totalS < 3600*24) { 82 | totalDuration = df.format((double) totalS / 3600) + "时"; 83 | } 84 | 85 | return totalDuration; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/DataLoadCallBack.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.ui; 2 | 3 | import android.content.Context; 4 | 5 | public interface DataLoadCallBack { 6 | 7 | public void loadData(Context context); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/GifProductsListAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Djia 3 | * All right reserved. 4 | * 5 | * Created on 2014-8-7 6 | */ 7 | package com.wind.gifassistant.ui; 8 | 9 | import java.util.ArrayList; 10 | 11 | import android.content.Context; 12 | import android.util.Log; 13 | import android.view.LayoutInflater; 14 | import android.view.View; 15 | import android.view.ViewGroup; 16 | import android.widget.BaseAdapter; 17 | import android.widget.TextView; 18 | 19 | import com.wind.gifassistant.R; 20 | import com.wind.gifassistant.data.GifProductInfo; 21 | import com.wind.gifassistant.utils.AppConfigs; 22 | import com.wind.gifassistant.views.gifview.GifView; 23 | import com.wind.gifassistant.views.gifview.GifView.GifShowGravity; 24 | 25 | /** 26 | * 27 | * @author Djia 28 | * @time 2014-8-7上午10:29:40 29 | * @instuction 30 | */ 31 | public class GifProductsListAdapter extends BaseAdapter { 32 | final private LayoutInflater mInflater; 33 | final private ArrayList mListItem; 34 | final private static String TAG = AppConfigs.APP_TAG + "GifProductsListAdapter"; 35 | final private static boolean DEBUG = true; 36 | 37 | /** 38 | * 39 | */ 40 | public GifProductsListAdapter(Context context, ArrayList listItem) { 41 | mInflater = LayoutInflater.from(context); 42 | mListItem = listItem; 43 | } 44 | 45 | /* (non-Javadoc) 46 | * @see android.widget.Adapter#getCount() 47 | */ 48 | @Override 49 | public int getCount() { 50 | // TODO Auto-generated method stub 51 | return mListItem.size(); 52 | } 53 | 54 | /* (non-Javadoc) 55 | * @see android.widget.Adapter#getItem(int) 56 | */ 57 | @Override 58 | public Object getItem(int pos) { 59 | // TODO Auto-generated method stub 60 | if (pos < 1) { 61 | return null; 62 | } 63 | if (pos > mListItem.size()) { 64 | return null; 65 | } 66 | 67 | return mListItem.get((pos-1)); 68 | } 69 | 70 | /* (non-Javadoc) 71 | * @see android.widget.Adapter#getItemId(int) 72 | */ 73 | @Override 74 | public long getItemId(int arg0) { 75 | // TODO Auto-generated method stub 76 | return 0; 77 | } 78 | 79 | public final class ViewHolder{ 80 | public GifView gif; 81 | public TextView name; 82 | public TextView time; 83 | public TextView fileSize; 84 | } 85 | 86 | /* (non-Javadoc) 87 | * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup) 88 | */ 89 | @Override 90 | public View getView(int position, View convertView, ViewGroup parent) { 91 | ViewHolder holder = null; 92 | if (convertView == null) { 93 | holder=new ViewHolder(); 94 | convertView = mInflater.inflate(R.layout.gif_products_list_item, null); 95 | holder.gif = (GifView)convertView.findViewById(R.id.gif_product); 96 | holder.name = (TextView)convertView.findViewById(R.id.gif_product_name); 97 | holder.time = (TextView)convertView.findViewById(R.id.gif_product_created_time); 98 | holder.fileSize = (TextView) convertView.findViewById(R.id.gif_product_file_size); 99 | convertView.setTag(holder); 100 | }else { 101 | logd("convertView != null, reuse"); 102 | holder = (ViewHolder)convertView.getTag(); 103 | } 104 | 105 | GifProductInfo gifInfo = new GifProductInfo(mListItem.get(position)); 106 | holder.gif.setGifShowGravity(GifShowGravity.CENTER_FULL); 107 | holder.gif.showGifImage(gifInfo.getPath(), true); 108 | holder.name.setText("文件名:" + gifInfo.getName()); 109 | holder.time.setText("时间:" + gifInfo.getLastModifyTime()); 110 | holder.fileSize.setText("大小:" + gifInfo.getFileSize()); 111 | 112 | return convertView; 113 | } 114 | 115 | private static void logd(String message) { 116 | if(DEBUG) { 117 | Log.d(TAG, message); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/MaxTimeRangSettingListener.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.ui; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | import com.wind.gifassistant.utils.AppConfigs; 7 | import com.wind.gifassistant.utils.AppUtils; 8 | 9 | /** 10 | * Created by djia on 15-5-7. 11 | */ 12 | public class MaxTimeRangSettingListener implements RangSettingListener { 13 | 14 | final Context mContext; 15 | final SharedPreferences mSharedPreferences; 16 | 17 | public MaxTimeRangSettingListener(Context context, SharedPreferences sp) { 18 | mContext = context; 19 | mSharedPreferences = sp; 20 | } 21 | 22 | @Override 23 | public boolean commitRangSetting(int current) { 24 | return AppConfigs.setGifProductMaxTimeSetting(mSharedPreferences, current); 25 | } 26 | 27 | @Override 28 | public RangValues getCurrentRang() { 29 | int current = 30 | AppConfigs.getGifProductMaxTimeSetting(mSharedPreferences); 31 | return new RangValues( 32 | AppUtils.DEFAULT_MAX_TIME_MAX_VALUE, 33 | AppUtils.DEFAULT_MAX_TIME_MIN_VALUE, current); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/RangSettingDialog.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.ui; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import android.content.DialogInterface; 6 | import android.os.Bundle; 7 | import android.widget.TextView; 8 | 9 | import com.wind.gifassistant.R; 10 | import com.wind.gifassistant.ui.textpicker.TextPicker; 11 | import com.wind.gifassistant.utils.AppUtils; 12 | 13 | /** 14 | * Created by djia on 15-4-21. 15 | */ 16 | public class RangSettingDialog extends Dialog implements DialogInterface.OnDismissListener { 17 | 18 | private String mTitleStr; 19 | private TextView mTitleView; 20 | private String mTipsStr; 21 | private TextView mTipsView; 22 | private String mUnitStr; 23 | private TextView mUnitTextView; 24 | 25 | private TextPicker mPicker; 26 | 27 | private Context mContext; 28 | 29 | private RangSettingListener listener; 30 | 31 | public RangSettingDialog(Context context) { 32 | this(context, R.style.popup_dialog); 33 | } 34 | 35 | private RangSettingDialog(Context context, int theme) { 36 | super(context, theme); 37 | mContext = context; 38 | setOnDismissListener(this); 39 | } 40 | 41 | public void setDialogTitle(String title) { 42 | mTitleStr = title; 43 | } 44 | 45 | public void setDialogTitle(int titleResId) { 46 | mTitleStr = mContext.getResources().getString(titleResId); 47 | } 48 | 49 | public void setUnitText(String unit) { 50 | mUnitStr = unit; 51 | } 52 | 53 | public void setUnitText(int unitResId) { 54 | mUnitStr = mContext.getResources().getString(unitResId); 55 | } 56 | 57 | public void setTips(String tips) { 58 | mTipsStr = tips; 59 | } 60 | 61 | public void setTips(int tipsResId) { 62 | mTipsStr = mContext.getResources().getString(tipsResId); 63 | } 64 | 65 | public void setRangListener(RangSettingListener l) { 66 | listener = l; 67 | } 68 | 69 | @Override 70 | public void onCreate(Bundle savedInstanceState) { 71 | // TODO Auto-generated method stub 72 | super.onCreate(savedInstanceState); 73 | setContentView(R.layout.rang_setting_dialog); 74 | 75 | mTitleView = (TextView) findViewById(R.id.title); 76 | mTitleView.setText(mTitleStr); 77 | 78 | mTipsView = (TextView) findViewById(R.id.tips); 79 | mTipsView.setText(mTipsStr); 80 | mTipsView.setSelected(true); 81 | 82 | mUnitTextView = (TextView) findViewById(R.id.unit); 83 | mUnitTextView.setText(mUnitStr); 84 | 85 | mPicker = (TextPicker) findViewById(R.id.numberPicker); 86 | RangValues rangValues = null; 87 | if (listener != null) { 88 | rangValues = listener.getCurrentRang(); 89 | } 90 | int max = rangValues!=null ? rangValues.max : AppUtils.DEFAULT_RATE_MAX_VALUE; 91 | int min = rangValues!=null ? rangValues.min : AppUtils.DEFAULT_RATE_MIN_VALUE; 92 | int current = rangValues!=null ? rangValues.current : AppUtils.DEFAULT_RATE_VALUE; 93 | mPicker.setMaxValue(max); 94 | mPicker.setMinValue(min); 95 | mPicker.setValue(current); 96 | mPicker.setFocusable(true); 97 | mPicker.setFocusableInTouchMode(true); 98 | } 99 | 100 | @Override 101 | public void onDismiss(DialogInterface dialogInterface) { 102 | if (mPicker != null) { 103 | if (listener != null) { 104 | int current = mPicker.getValue(); 105 | listener.commitRangSetting(current); 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/RangSettingListener.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.ui; 2 | 3 | /** 4 | * Created by djia on 15-5-7. 5 | */ 6 | public interface RangSettingListener { 7 | 8 | /** 9 | * 将设定保存 10 | * @param current 设定值 11 | * @return 成功 true, 失败 false 12 | */ 13 | public boolean commitRangSetting(int current); 14 | 15 | /** 16 | * 获取当前的设定 17 | * @return 18 | */ 19 | public RangValues getCurrentRang(); 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/RangValues.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.ui; 2 | 3 | /** 4 | * Created by djia on 15-5-7. 5 | */ 6 | public class RangValues { 7 | 8 | public int max; 9 | public int min; 10 | public int current; 11 | 12 | /** 13 | * 14 | * @param m 最大值 15 | * @param i 最小值 16 | * @param c 当前值 17 | */ 18 | public RangValues(int m, int i, int c) { 19 | max = m; 20 | min = i; 21 | current = c; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/RateRangSettingListener.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.ui; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | import com.wind.gifassistant.utils.AppConfigs; 7 | import com.wind.gifassistant.utils.AppUtils; 8 | 9 | /** 10 | * Created by djia on 15-5-7. 11 | */ 12 | public class RateRangSettingListener implements RangSettingListener { 13 | 14 | final Context mContext; 15 | final SharedPreferences mSharedPreferences; 16 | 17 | public RateRangSettingListener(Context context, SharedPreferences sp) { 18 | mContext = context; 19 | mSharedPreferences = sp; 20 | } 21 | 22 | @Override 23 | public boolean commitRangSetting(int current) { 24 | return AppConfigs.setGifProductFrameRateSetting(mSharedPreferences, current); 25 | } 26 | 27 | @Override 28 | public RangValues getCurrentRang() { 29 | int current = 30 | AppConfigs.getGifProductFrameRateSetting(mSharedPreferences); 31 | return new RangValues( 32 | AppUtils.DEFAULT_RATE_MAX_VALUE, 33 | AppUtils.DEFAULT_RATE_MIN_VALUE, current); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/VideosListAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Djia 3 | * All right reserved. 4 | * 5 | * Created on 2014-8-12 6 | */ 7 | package com.wind.gifassistant.ui; 8 | 9 | import java.util.ArrayList; 10 | 11 | import android.content.Context; 12 | import android.media.ThumbnailUtils; 13 | import android.provider.MediaStore.Video.Thumbnails; 14 | import android.util.Log; 15 | import android.view.LayoutInflater; 16 | import android.view.View; 17 | import android.view.ViewGroup; 18 | import android.widget.BaseAdapter; 19 | import android.widget.ImageView; 20 | import android.widget.TextView; 21 | 22 | import com.wind.gifassistant.R; 23 | import com.wind.gifassistant.data.ExtractPicturesWorker; 24 | import com.wind.gifassistant.data.VideosInfo; 25 | import com.wind.gifassistant.utils.AppConfigs; 26 | 27 | /** 28 | * 29 | * @author Djia 30 | * @time 2014-8-12下午1:33:10 31 | * @instuction 32 | */ 33 | public class VideosListAdapter extends BaseAdapter { 34 | final private LayoutInflater mInflater; 35 | final private ArrayList mVideosPaths; 36 | final private static String TAG = AppConfigs.APP_TAG + "VideosListAdapter"; 37 | final private static boolean DEBUG = true; 38 | 39 | /** 40 | * 41 | */ 42 | public VideosListAdapter(Context context, ArrayList pathList) { 43 | // TODO Auto-generated constructor stub 44 | mInflater = LayoutInflater.from(context); 45 | mVideosPaths = pathList; 46 | } 47 | 48 | /* (non-Javadoc) 49 | * @see android.widget.Adapter#getCount() 50 | */ 51 | @Override 52 | public int getCount() { 53 | // TODO Auto-generated method stub 54 | return mVideosPaths.size(); 55 | } 56 | 57 | /* (non-Javadoc) 58 | * @see android.widget.Adapter#getItem(int) 59 | */ 60 | @Override 61 | public Object getItem(int pos) { 62 | // TODO Auto-generated method stub 63 | if (pos < 1) { 64 | return null; 65 | } 66 | if (pos > mVideosPaths.size()) { 67 | return null; 68 | } 69 | 70 | return mVideosPaths.get((pos-1)); 71 | } 72 | 73 | /* (non-Javadoc) 74 | * @see android.widget.Adapter#getItemId(int) 75 | */ 76 | @Override 77 | public long getItemId(int position) { 78 | // TODO Auto-generated method stub 79 | return 0; 80 | } 81 | 82 | private final class ViewHolder{ 83 | public ImageView thumb; 84 | public TextView name; 85 | public TextView time; 86 | public TextView duration; 87 | } 88 | 89 | /* (non-Javadoc) 90 | * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup) 91 | */ 92 | @Override 93 | public View getView(int position, View convertView, ViewGroup parent) { 94 | ViewHolder holder = null; 95 | if (convertView == null) { 96 | holder=new ViewHolder(); 97 | convertView = mInflater.inflate(R.layout.videos_list_item, null); 98 | holder.thumb = (ImageView)convertView.findViewById(R.id.video_thumb); 99 | holder.name = (TextView)convertView.findViewById(R.id.video_name); 100 | holder.time = (TextView)convertView.findViewById(R.id.video_file_created_time); 101 | holder.duration = (TextView) convertView.findViewById(R.id.video_total_duration); 102 | convertView.setTag(holder); 103 | }else { 104 | logd("convertView != null, reuse"); 105 | holder = (ViewHolder)convertView.getTag(); 106 | } 107 | 108 | VideosInfo videoInfo = new VideosInfo(mVideosPaths.get(position)); 109 | //holder.thumb.setImageBitmap(ExtractPicturesWorker.extractBitmap(mVideosPaths.get(position), 0)); 110 | holder.thumb.setImageBitmap(ThumbnailUtils.createVideoThumbnail(mVideosPaths.get(position), Thumbnails.MINI_KIND)); 111 | holder.name.setText("文件名:" + videoInfo.getName()); 112 | holder.time.setText("时间:" + videoInfo.getLastModifyTime()); 113 | holder.duration.setText("时长:" + videoInfo.getDuration()); 114 | 115 | return convertView; 116 | } 117 | 118 | private static void logd(String message) { 119 | if(DEBUG) { 120 | Log.d(TAG, message); 121 | } 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/ui/WelcomeActivity.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Djia 3 | * All right reserved. 4 | * 5 | * Created on 2014-7-1 6 | */ 7 | package com.wind.gifassistant.ui; 8 | 9 | import android.app.Activity; 10 | import android.content.Intent; 11 | import android.os.Bundle; 12 | import android.view.KeyEvent; 13 | import android.view.animation.Animation; 14 | import android.view.animation.Animation.AnimationListener; 15 | import android.view.animation.AnimationUtils; 16 | import android.widget.ImageView; 17 | 18 | import com.wind.gifassistant.R; 19 | import com.wind.gifassistant.utils.AppConfigs; 20 | 21 | /** 22 | * 23 | * @author Djia 24 | * @time 2014-7-1上午10:45:37 25 | * @instuction 欢迎界面 26 | */ 27 | public class WelcomeActivity extends Activity implements AnimationListener { 28 | 29 | private ImageView imageView = null; 30 | private Animation alphaAnimation = null; 31 | 32 | /** 33 | * 播放一个动画进行过度。。。 34 | */ 35 | public WelcomeActivity() { 36 | // TODO Auto-generated constructor stub 37 | } 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | // TODO Auto-generated method stub 42 | super.onCreate(savedInstanceState); 43 | setContentView(R.layout.welcome); 44 | imageView = (ImageView)findViewById(R.id.welcome_image_view); 45 | alphaAnimation = AnimationUtils.loadAnimation(this, R.anim.welcome_alpha); 46 | alphaAnimation.setFillEnabled(true); //启动Fill保持 47 | alphaAnimation.setFillAfter(true); //设置动画的最后一帧是保持在View上面 48 | imageView.setAnimation(alphaAnimation); 49 | alphaAnimation.setAnimationListener(this); //为动画设置监听 50 | doInitWork(); 51 | } 52 | 53 | @Override 54 | public boolean onKeyDown(int keyCode, KeyEvent event) { 55 | // TODO Auto-generated method stub 56 | if(keyCode == KeyEvent.KEYCODE_BACK) { 57 | return false; 58 | } 59 | return false; 60 | } 61 | 62 | private void doInitWork() { 63 | //AppConfigs.checkAndCreateNecessaryFolders(); 64 | } 65 | 66 | /* (non-Javadoc) 67 | * @see android.view.animation.Animation.AnimationListener#onAnimationEnd(android.view.animation.Animation) 68 | */ 69 | @Override 70 | public void onAnimationEnd(Animation arg0) { 71 | // TODO Auto-generated method stub 72 | //动画结束时结束欢迎界面并转到软件的主界面 73 | Intent intent = new Intent(WelcomeActivity.this, MainActivity.class); 74 | WelcomeActivity.this.startActivity(intent); 75 | WelcomeActivity.this.finish(); 76 | } 77 | 78 | /* (non-Javadoc) 79 | * @see android.view.animation.Animation.AnimationListener#onAnimationRepeat(android.view.animation.Animation) 80 | */ 81 | @Override 82 | public void onAnimationRepeat(Animation animation) { 83 | // TODO Auto-generated method stub 84 | 85 | } 86 | 87 | /* (non-Javadoc) 88 | * @see android.view.animation.Animation.AnimationListener#onAnimationStart(android.view.animation.Animation) 89 | */ 90 | @Override 91 | public void onAnimationStart(Animation animation) { 92 | // TODO Auto-generated method stub 93 | 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/utils/AppUtils.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.utils; 2 | 3 | import android.os.Environment; 4 | 5 | public class AppUtils { 6 | public static final int MENU_DELETE = 0; 7 | public static final int MENU_SHOW = 1; 8 | public static final int MENU_DELETE_ALL = 2; 9 | 10 | public static final int FILE_TYPE_GIF = 0; 11 | public static final int FILE_TYPE_VIDEO = 1; 12 | 13 | // Root path 14 | public static final String APP_ROOT_DIRECTORY_NAME = "gif_assistant"; 15 | public static final String APP_ABSOLUTE_ROOT_PATH = Environment 16 | .getExternalStorageDirectory().toString() + "/" + APP_ROOT_DIRECTORY_NAME; 17 | 18 | // gif 作品库 19 | public static final String GIF_PRODUCTS_FOLDER_NAME = "products"; 20 | public static final String GIF_PRODUCTS_FOLDER_PATH = APP_ABSOLUTE_ROOT_PATH + "/" + GIF_PRODUCTS_FOLDER_NAME; 21 | 22 | // videos folder, maybe not be needed 23 | public static final String VIDEOS_FOLDER_NAME = "videos"; 24 | public static final String VIDEOS_FOLDER_PATH = APP_ABSOLUTE_ROOT_PATH + "/" + VIDEOS_FOLDER_NAME; 25 | 26 | // crash path 27 | public static final String APP_CRASH_FOLDER_NAME = "crash_log"; 28 | public static final String APP_CRASH_PATH = APP_ABSOLUTE_ROOT_PATH + "/" + APP_CRASH_FOLDER_NAME; 29 | 30 | // temp file folder 31 | public static final String APP_GIF_TEMP_FILES_FOLDER_NAME = "temp_files"; 32 | public static final String APP_GIF_TEMP_FILES_FOLDER_PATH = APP_ABSOLUTE_ROOT_PATH + "/" + APP_GIF_TEMP_FILES_FOLDER_NAME; 33 | 34 | public static final String KEY_PATH = "file_path"; 35 | public static final String KEY_RESIDE_MENU_BACKGROUD = "reside_menu_backgroud"; 36 | 37 | public static final String KEY_GIF_PRODUCT_FRAME_RATE = "gif_frame_rate"; 38 | public static final String KEY_GIF_PRODUCT_delay = "gif_delay"; 39 | public static final String KEY_GIF_PRODUCT_SCALE = "gif_scale"; 40 | public static final String KEY_GIF_PRODUCT_MAX_TIME = "max_time"; 41 | 42 | public static final int GIF_SCALE_VALUE_1 = 1; 43 | public static final int GIF_SCALE_VALUE_2 = 2; 44 | public static final int GIF_SCALE_VALUE_3 = 3; 45 | public static final int GIF_SCALE_VALUE_4 = 4; 46 | public static final int GIF_SCALE_VALUE_5 = 5; 47 | public static final int DEFAULT_SCALE_VALUE = GIF_SCALE_VALUE_2; 48 | 49 | 50 | public static final int DEFAULT_RATE_VALUE = 15; 51 | public static final int DEFAULT_RATE_MIN_VALUE = 5; 52 | public static final int DEFAULT_RATE_MAX_VALUE = 25; 53 | 54 | public static final int DEFAULT_MAX_TIME_VALUE = 10; 55 | public static final int DEFAULT_MAX_TIME_MAX_VALUE = 15; 56 | public static final int DEFAULT_MAX_TIME_MIN_VALUE = 2; 57 | 58 | public static final String SHARED_PREFERENCE_NAME = "gif_product_infos"; 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/views/SoundView.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Copyright 2014 Djia 4 | * All right reserved. 5 | * 6 | * Author: Djia, Created on 2014-6-30 7 | */ 8 | package com.wind.gifassistant.views; 9 | 10 | import android.content.Context; 11 | import android.graphics.Bitmap; 12 | import android.graphics.BitmapFactory; 13 | import android.graphics.Canvas; 14 | import android.graphics.Rect; 15 | import android.media.AudioManager; 16 | import android.util.AttributeSet; 17 | import android.util.Log; 18 | import android.view.MotionEvent; 19 | import android.view.View; 20 | 21 | import com.wind.gifassistant.R; 22 | import com.wind.gifassistant.utils.AppConfigs; 23 | 24 | /** 25 | * @author Djia 26 | * 2014-6-30 27 | */ 28 | 29 | public class SoundView extends View { 30 | public final static String TAG = AppConfigs.APP_TAG + "SoundView"; 31 | 32 | private Context mContext; 33 | private Bitmap bm , bm1; 34 | private int bitmapWidth , bitmapHeight; 35 | private int index; 36 | private OnVolumeChangedListener mOnVolumeChangedListener; 37 | 38 | private final static int HEIGHT = 11; 39 | public final static int MY_HEIGHT = 163; 40 | public final static int MY_WIDTH = 44; 41 | 42 | public interface OnVolumeChangedListener{ 43 | public void setVolume(int index); 44 | } 45 | 46 | public void setOnVolumeChangeListener(OnVolumeChangedListener l){ 47 | mOnVolumeChangedListener = l; 48 | } 49 | 50 | /** 51 | * @param context 52 | */ 53 | public SoundView(Context context) { 54 | super(context); 55 | // TODO Auto-generated constructor stub 56 | mContext = context; 57 | init(); 58 | } 59 | 60 | /** 61 | * @param context 62 | * @param attrs 63 | */ 64 | public SoundView(Context context, AttributeSet attrs) { 65 | super(context, attrs); 66 | // TODO Auto-generated constructor stub 67 | mContext = context; 68 | init(); 69 | } 70 | 71 | /** 72 | * @param context 73 | * @param attrs 74 | * @param defStyle 75 | */ 76 | public SoundView(Context context, AttributeSet attrs, int defStyle) { 77 | super(context, attrs, defStyle); 78 | // TODO Auto-generated constructor stub 79 | mContext = context; 80 | init(); 81 | } 82 | 83 | private void init(){ 84 | bm = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.sound_line); 85 | bm1 = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.sound_line1); 86 | bitmapWidth = bm.getWidth(); 87 | bitmapHeight = bm.getHeight(); 88 | //setIndex(5); 89 | AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); 90 | setIndex(am.getStreamVolume(AudioManager.STREAM_MUSIC)); 91 | } 92 | 93 | @Override 94 | public boolean onTouchEvent(MotionEvent event) { 95 | // TODO Auto-generated method stub 96 | 97 | int y = (int) event.getY(); 98 | int n = y * 15 / MY_HEIGHT; 99 | setIndex(15-n); 100 | Log.d(TAG, "setIndex: "+(15-n)); 101 | 102 | 103 | return true; 104 | } 105 | 106 | @Override 107 | protected void onDraw(Canvas canvas) { 108 | // TODO Auto-generated method stub 109 | 110 | int reverseIndex = 15 - index; 111 | for(int i = 0;i!=reverseIndex;++i){ 112 | canvas.drawBitmap(bm1, new Rect(0,0,bitmapWidth,bitmapHeight), 113 | new Rect(0,i*HEIGHT,bitmapWidth,i*HEIGHT+bitmapHeight), null); 114 | } 115 | for(int i = reverseIndex;i!=15;++i){ 116 | canvas.drawBitmap(bm, new Rect(0,0,bitmapWidth,bitmapHeight), 117 | new Rect(0,i*HEIGHT,bitmapWidth,i*HEIGHT+bitmapHeight), null); 118 | } 119 | 120 | super.onDraw(canvas); 121 | } 122 | 123 | private void setIndex(int n){ 124 | if(n>15){ 125 | n = 15; 126 | } 127 | else if(n<0){ 128 | n = 0; 129 | } 130 | if(index!=n){ 131 | index = n; 132 | if(mOnVolumeChangedListener!=null){ 133 | mOnVolumeChangedListener.setVolume(n); 134 | } 135 | } 136 | invalidate(); 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/views/gifview/GifAction.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.views.gifview; 2 | 3 | public interface GifAction { 4 | 5 | /** 6 | * gif解码观察者 7 | * @param parseStatus 解码是否成功,成功会为true 8 | * @param frameIndex 当前解码的第几帧,当全部解码成功后,这里为-1 9 | */ 10 | public void parseOk(boolean parseStatus,int frameIndex); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/views/gifview/GifFrame.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.views.gifview; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | public class GifFrame { 6 | /** 7 | * 构造函数 8 | * @param im 图片 9 | * @param del 延时 10 | */ 11 | public GifFrame(Bitmap im, int del) { 12 | image = im; 13 | delay = del; 14 | } 15 | /**图片*/ 16 | public Bitmap image; 17 | /**延时*/ 18 | public int delay; 19 | /**下一帧*/ 20 | public GifFrame nextFrame = null; 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/views/waveview/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014 Romain Piel 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /app/src/main/java/com/wind/gifassistant/views/waveview/Typefaces.java: -------------------------------------------------------------------------------- 1 | package com.wind.gifassistant.views.waveview; 2 | 3 | import android.content.Context; 4 | import android.graphics.Typeface; 5 | import android.util.Log; 6 | 7 | import java.util.Hashtable; 8 | 9 | public class Typefaces { 10 | private static final String TAG = "Typefaces"; 11 | private static final Hashtable cache = new Hashtable(); 12 | 13 | public static Typeface get(Context c, String assetPath) { 14 | synchronized (cache) { 15 | if (!cache.containsKey(assetPath)) { 16 | try { 17 | Typeface t = Typeface.createFromAsset(c.getAssets(), assetPath); 18 | cache.put(assetPath, t); 19 | } catch (Exception e) { 20 | Log.e(TAG, "Could not get typeface '" + assetPath + "' because " + e.getMessage()); 21 | return null; 22 | } 23 | } 24 | 25 | return cache.get(assetPath); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libavcodec-56.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/jniLibs/armeabi/libavcodec-56.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libavdevice-56.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/jniLibs/armeabi/libavdevice-56.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libavfilter-5.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/jniLibs/armeabi/libavfilter-5.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libavformat-56.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/jniLibs/armeabi/libavformat-56.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libavutil-54.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/jniLibs/armeabi/libavutil-54.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libffmpegjni.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/jniLibs/armeabi/libffmpegjni.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libswresample-1.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/jniLibs/armeabi/libswresample-1.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libswscale-3.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/jniLibs/armeabi/libswscale-3.so -------------------------------------------------------------------------------- /app/src/main/res/anim/nav_1_battery_rotate.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 15 | 16 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/anim/nav_1_zoom_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/anim/nav_2_everything_show.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_from_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_to_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_to_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/welcome_alpha.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dxjia/GifAssistant/6ec4e6f790d34621e08c811a1354af465fbc98e5/app/src/main/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/checkbox_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |     4 |    8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_bottom_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |     4 |    6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_bottom_pressed_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 |    8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_bottom_selector_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_pressed_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 |    10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_selector_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_top_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |     4 |    6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_top_pressed_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 |    8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/corners_top_selector_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/dialog_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/fab_label_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/indicator_bg_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/indicator_bg_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/item_background_holo_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/item_background_holo_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/list_selector_background_transition_holo_dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/list_selector_background_transition_holo_light.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/nav_1_time_show_animation.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/nav_3_rocket_animation.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 11 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/nav_4_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/reside_menu_text_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/skip_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/titlebar_menu_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/gif_products_list_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 12 | 17 | 23 | 24 | 30 | 31 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/gif_quality_setting_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 21 | 22 | 28 | 37 | 38 | 47 | 56 | 57 | 66 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /app/src/main/res/layout/gif_show_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 31 | 32 | 39 | 40 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/res/layout/main_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 17 | 21 |