├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── dictionaries │ └── oceancx.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── oceancx │ │ └── androidlib │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── oceancx │ │ │ └── androidlib │ │ │ ├── Constants.java │ │ │ ├── DebugLog.java │ │ │ ├── MainActivity.java │ │ │ ├── QA │ │ │ └── ListViewContainsEditText.java │ │ │ ├── dialog │ │ │ ├── DialogTemplate.java │ │ │ └── FgHelper.java │ │ │ ├── main │ │ │ ├── CheckBoxActivity.java │ │ │ ├── MediaPlayerActivity.java │ │ │ ├── PullToRefreshAndLoadMoreActivity.java │ │ │ └── RangeSeekActivity.java │ │ │ ├── popupwindow │ │ │ ├── FilterGridPw.java │ │ │ ├── FilterLinePw.java │ │ │ └── PwTemplate.java │ │ │ ├── simpleclass │ │ │ ├── DumbViewHolder.java │ │ │ └── TextWatcherAdapter.java │ │ │ ├── utils │ │ │ ├── CacheHelper.java │ │ │ ├── DateUtils.java │ │ │ ├── FileHelper.java │ │ │ ├── FormatedTime.java │ │ │ └── MeasureUtils.java │ │ │ └── widget │ │ │ ├── AdvancedRadioGroup.java │ │ │ ├── DashedLine.java │ │ │ ├── DashedOval.java │ │ │ ├── ExpandableListViewForScrollView.java │ │ │ ├── FrameLayoutCheckBox.java │ │ │ ├── PullToRefreshRecyclerView.java │ │ │ ├── RSlidingPaneLayout.java │ │ │ └── TranslusantView.java │ └── res │ │ ├── drawable-mdpi │ │ ├── loading_50x50_1.png │ │ ├── loading_50x50_10.png │ │ ├── loading_50x50_11.png │ │ ├── loading_50x50_12.png │ │ ├── loading_50x50_2.png │ │ ├── loading_50x50_3.png │ │ ├── loading_50x50_4.png │ │ ├── loading_50x50_5.png │ │ ├── loading_50x50_6.png │ │ ├── loading_50x50_7.png │ │ ├── loading_50x50_8.png │ │ └── loading_50x50_9.png │ │ ├── drawable │ │ ├── cbx_filter_bg.xml │ │ ├── cbx_tag_text_color.xml │ │ ├── dis_ripple.xml │ │ ├── filter_txt_color.xml │ │ ├── music_pgb_drawable.xml │ │ ├── pgb_circle.xml │ │ ├── round_rect_2dp_grey_border.xml │ │ ├── round_rect_2dp_main_blue.xml │ │ ├── round_white_rect.xml │ │ ├── shape_circle_white.xml │ │ └── tag_tv_bg.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── checkbox_activity.xml │ │ ├── dialog_template.xml │ │ ├── divider_grey_e6e7ea.xml │ │ ├── item_view.xml │ │ ├── line_popupwindow.xml │ │ ├── line_popupwindow_cbx.xml │ │ ├── line_popupwindow_rbt.xml │ │ ├── media_player_activity.xml │ │ ├── pull_to_fresh_and_loadmore_activity.xml │ │ ├── pull_to_refresh_body.xml │ │ ├── range_seekbar_activity.xml │ │ ├── tag_popupwindow.xml │ │ ├── tag_pw_checkbox.xml │ │ ├── view_open_time_pw.xml │ │ └── view_open_time_pw_item.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── oceancx │ └── androidlib │ └── ExampleUnitTest.java ├── build.gradle ├── gif └── range_seekbar.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── pulltorefreshandloadmore ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── oceancx │ │ └── pulltorefreshandloadmore │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── oceancx │ │ │ └── pulltorefreshandloadmore │ │ │ ├── DebugLog.java │ │ │ └── PullToFreshAndLordMoreLayout.java │ └── res │ │ ├── drawable-hdpi │ │ └── ic_arrow_downward_black_18dp.png │ │ ├── drawable-mdpi │ │ ├── ic_arrow_downward_black_18dp.png │ │ ├── loading_50x50_1.png │ │ ├── loading_50x50_10.png │ │ ├── loading_50x50_11.png │ │ ├── loading_50x50_12.png │ │ ├── loading_50x50_2.png │ │ ├── loading_50x50_3.png │ │ ├── loading_50x50_4.png │ │ ├── loading_50x50_5.png │ │ ├── loading_50x50_6.png │ │ ├── loading_50x50_7.png │ │ ├── loading_50x50_8.png │ │ └── loading_50x50_9.png │ │ ├── drawable-xhdpi │ │ └── ic_arrow_downward_black_18dp.png │ │ ├── drawable-xxhdpi │ │ └── ic_arrow_downward_black_18dp.png │ │ ├── drawable-xxxhdpi │ │ └── ic_arrow_downward_black_18dp.png │ │ ├── drawable │ │ └── pgb_circle.xml │ │ ├── layout │ │ ├── pull_to_refresh_footer.xml │ │ └── pull_to_refresh_header.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── oceancx │ └── pulltorefreshandloadmore │ └── ExampleUnitTest.java ├── rangeseekbar ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── oceancx │ │ └── rangeseekbar │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── oceancx │ │ │ └── rangeseekbar │ │ │ └── RangeSeekBar.java │ └── res │ │ └── values │ │ ├── attrs.xml │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── oceancx │ └── rangeseekbar │ └── ExampleUnitTest.java ├── readme.md ├── settings.gradle └── uilib ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── oceancx │ └── uilib │ └── ApplicationTest.java ├── main ├── AndroidManifest.xml └── res │ └── values │ └── strings.xml └── test └── java └── com └── oceancx └── uilib └── ExampleUnitTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | AndroidLib -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/dictionaries/oceancx.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 29 | 30 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 26 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Android Lint 46 | 47 | 48 | Assignment issuesJava 49 | 50 | 51 | Bitwise operation issuesJava 52 | 53 | 54 | Class structureJava 55 | 56 | 57 | Code maturity issuesJava 58 | 59 | 60 | Code style issuesJava 61 | 62 | 63 | Control flow issuesJava 64 | 65 | 66 | Groovy 67 | 68 | 69 | Inheritance issuesJava 70 | 71 | 72 | Internationalization issues 73 | 74 | 75 | Internationalization issuesJava 76 | 77 | 78 | JUnit issuesJava 79 | 80 | 81 | Java 82 | 83 | 84 | Java language level migration aidsJava 85 | 86 | 87 | Javadoc issuesJava 88 | 89 | 90 | Naming conventionsJava 91 | 92 | 93 | Numeric issuesJava 94 | 95 | 96 | Performance issuesJava 97 | 98 | 99 | Potentially confusing code constructsGroovy 100 | 101 | 102 | Probable bugsJava 103 | 104 | 105 | Resource management issuesJava 106 | 107 | 108 | TestNG 109 | 110 | 111 | Threading issuesJava 112 | 113 | 114 | 115 | 116 | AndroidLintEnforceUTF8 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 138 | 139 | 140 | 141 | 142 | 143 | 148 | 149 | 150 | 151 | 152 | 153 | 1.7 154 | 155 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.oceancx.androidlib" 9 | minSdkVersion 14 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.1.1' 26 | compile 'com.android.support:recyclerview-v7:23.1.1' 27 | compile project(':rangeseekbar') 28 | compile project(':pulltorefreshandloadmore') 29 | } 30 | -------------------------------------------------------------------------------- /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 /Users/oceancx/Development/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/oceancx/androidlib/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib; 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 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/Constants.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib; 2 | 3 | /** 4 | * Created by oceancx on 16/1/30. 5 | */ 6 | public class Constants { 7 | public static final long MIOJI_SAY_ANIM_DURATION = 300; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/DebugLog.java: -------------------------------------------------------------------------------- 1 | /*** 2 | This is free and unencumbered software released into the public domain. 3 | 4 | Anyone is free to copy, modify, publish, use, compile, sell, or 5 | distribute this software, either in source code form or as a compiled 6 | binary, for any purpose, commercial or non-commercial, and by any 7 | means. 8 | 9 | For more information, please refer to 10 | */ 11 | 12 | package com.oceancx.androidlib; 13 | 14 | import android.util.Log; 15 | 16 | 17 | /** 18 | * @date 21.06.2012 19 | * @author Mustafa Ferhan Akman 20 | * 21 | * Create a simple and more understandable Android logs. 22 | * */ 23 | 24 | public class DebugLog { 25 | 26 | static String className; 27 | static String methodName; 28 | static int lineNumber; 29 | 30 | private DebugLog(){ 31 | /* Protect from instantiations */ 32 | } 33 | 34 | public static boolean isDebuggable() { 35 | return true; 36 | } 37 | 38 | private static String createLog( String log ) { 39 | 40 | StringBuffer buffer = new StringBuffer(); 41 | buffer.append("["); 42 | buffer.append(methodName); 43 | buffer.append(":"); 44 | buffer.append(lineNumber); 45 | buffer.append("]"); 46 | buffer.append(log); 47 | 48 | return buffer.toString(); 49 | } 50 | 51 | private static void getMethodNames(StackTraceElement[] sElements){ 52 | className = sElements[1].getFileName(); 53 | methodName = sElements[1].getMethodName(); 54 | lineNumber = sElements[1].getLineNumber(); 55 | } 56 | 57 | public static void e(String message){ 58 | if (!isDebuggable()) 59 | return; 60 | 61 | // Throwable instance must be created before any methods 62 | getMethodNames(new Throwable().getStackTrace()); 63 | Log.e(className, createLog(message)); 64 | } 65 | 66 | public static void i(String message){ 67 | if (!isDebuggable()) 68 | return; 69 | 70 | getMethodNames(new Throwable().getStackTrace()); 71 | Log.i(className, createLog(message)); 72 | } 73 | 74 | public static void d(String message){ 75 | if (!isDebuggable()) 76 | return; 77 | 78 | getMethodNames(new Throwable().getStackTrace()); 79 | Log.d(className, createLog(message)); 80 | } 81 | 82 | public static void v(String message){ 83 | if (!isDebuggable()) 84 | return; 85 | 86 | getMethodNames(new Throwable().getStackTrace()); 87 | Log.v(className, createLog(message)); 88 | } 89 | 90 | public static void w(String message){ 91 | if (!isDebuggable()) 92 | return; 93 | 94 | getMethodNames(new Throwable().getStackTrace()); 95 | Log.w(className, createLog(message)); 96 | } 97 | 98 | public static void wtf(String message){ 99 | if (!isDebuggable()) 100 | return; 101 | 102 | getMethodNames(new Throwable().getStackTrace()); 103 | Log.wtf(className, createLog(message)); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib; 2 | 3 | import android.app.ListActivity; 4 | import android.content.Intent; 5 | import android.content.pm.ActivityInfo; 6 | import android.content.pm.PackageInfo; 7 | import android.content.pm.PackageManager; 8 | import android.os.Bundle; 9 | import android.view.View; 10 | import android.widget.AdapterView; 11 | import android.widget.ArrayAdapter; 12 | 13 | import java.util.ArrayList; 14 | import java.util.Arrays; 15 | 16 | public class MainActivity extends ListActivity { 17 | 18 | 19 | private ActivityInfo target; 20 | private ArrayList mActivities; 21 | private String packageName = "com.oceancx.androidlib"; 22 | private String desiredPackageName = "ListViewContainsEditText"; 23 | 24 | 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | 28 | ArrayList activity_names = new ArrayList(); 29 | mActivities = new ArrayList(); 30 | try { 31 | PackageInfo pi = getPackageManager().getPackageInfo(packageName, 32 | PackageManager.GET_ACTIVITIES); 33 | ArrayList allActivities = new ArrayList( 34 | Arrays.asList(pi.activities)); 35 | 36 | mActivities.add(allActivities.get(0)); 37 | 38 | for (int i = 0; i < allActivities.size(); i++) { 39 | String name = allActivities.get(i).name; 40 | mActivities.add(allActivities.get(i)); 41 | activity_names.add(name.substring(name.lastIndexOf(".") + 1, name.length())); 42 | if (name.contains(desiredPackageName)) { 43 | target = allActivities.get(i); 44 | } 45 | } 46 | 47 | } catch (PackageManager.NameNotFoundException e) { 48 | e.printStackTrace(); 49 | } 50 | ArrayAdapter adapter = new ArrayAdapter(this, 51 | android.R.layout.simple_list_item_1, android.R.id.text1, 52 | activity_names); 53 | 54 | getListView().setAdapter(adapter); 55 | getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() { 56 | 57 | @Override 58 | public void onItemClick(AdapterView parent, View view, 59 | int position, long id) { 60 | Intent intent = new Intent(); 61 | intent.setClassName(packageName, mActivities.get(position + 1).name); 62 | startActivity(intent); 63 | } 64 | 65 | }); 66 | if (target != null) { 67 | Intent intent = new Intent(); 68 | intent.setClassName(packageName, target.name); 69 | startActivity(intent); 70 | } 71 | } 72 | 73 | 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/QA/ListViewContainsEditText.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.QA; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.text.Editable; 7 | import android.text.TextWatcher; 8 | import android.view.MotionEvent; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.BaseAdapter; 12 | import android.widget.EditText; 13 | import android.widget.LinearLayout; 14 | import android.widget.ListView; 15 | 16 | import java.util.ArrayList; 17 | 18 | /** 19 | * EditText在ListView中的处理 20 | * Created by oceancx on 16/4/2. 21 | */ 22 | public class ListViewContainsEditText extends AppCompatActivity { 23 | ListView lv; 24 | ArrayList items = new ArrayList<>(); 25 | String content; 26 | int index = -1; 27 | 28 | @Override 29 | protected void onCreate(@Nullable Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | lv = new ListView(this); 32 | for (int i = 0; i < 30; i++) 33 | items.add("" + i); 34 | lv.setAdapter(new BaseAdapter() { 35 | 36 | @Override 37 | public int getCount() { 38 | return items.size(); 39 | } 40 | 41 | @Override 42 | public Object getItem(int position) { 43 | return null; 44 | } 45 | 46 | @Override 47 | public long getItemId(int position) { 48 | return 0; 49 | } 50 | 51 | @Override 52 | public View getView(int position, View convertView, ViewGroup parent) { 53 | if (convertView == null) { 54 | convertView = new LinearLayout(parent.getContext()); 55 | 56 | } else { 57 | // 因为项⽬目中每⼀一⾏行的控件究竟有什么都不确定,所以清掉layout⾥里的所有控件,你的项⽬目视情况⽽而定。 58 | 59 | ((LinearLayout) convertView).removeAllViews(); 60 | } 61 | 62 | 63 | // 不要直接new⼀一个Layout去赋值给convertView!!那样就不是重⽤用了,否则,后果⾃自负~~ 64 | EditText et = new EditText(parent.getContext()); 65 | // 你可以试试把addView放到这个函数的return之前,我保证你会后悔的~~ 66 | // addView的先后对画⾯面的结果是有影响的。 67 | ((LinearLayout) convertView).addView(et); 68 | et.setTag(position); 69 | 70 | 71 | 72 | et.setOnTouchListener(new View.OnTouchListener() { 73 | @Override 74 | public boolean onTouch(View v, MotionEvent event) { 75 | // 在TOUCH的UP事件中,要保存当前的⾏行下标,因为弹出软键盘后,整个画⾯面会被重画 76 | // 在getView⽅方法的最后,要根据index和当前的⾏行下标⼿手动为EditText设置焦点 77 | if (event.getAction() == MotionEvent.ACTION_UP) { 78 | index = (int) v.getTag(); 79 | } 80 | return false; 81 | } 82 | }); 83 | 84 | //这句要放在addTextWatcher之前 85 | et.setText(items.get(position)); 86 | et.addTextChangedListener(new TextWatcher() { 87 | @Override 88 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { 89 | 90 | } 91 | 92 | @Override 93 | public void onTextChanged(CharSequence s, int start, int before, int count) { 94 | // 在这个地⽅方添加你的保存⽂文本内容的代码,如果不保存,你就等着重新输⼊入吧 95 | // ⽽而且不管你输⼊入多少次,也不会有⽤用的,因为getView全清了~~ 96 | if (index != -1) { 97 | items.set(index, s.toString()); 98 | } 99 | } 100 | 101 | @Override 102 | public void afterTextChanged(Editable s) { 103 | } 104 | }); 105 | 106 | 107 | et.clearFocus(); 108 | if (position == index && index != -1) { 109 | // 如果当前的⾏行下标和点击事件中保存的index⼀一致,⼿手动为EditText设置焦点。 110 | et.requestFocus(); 111 | } 112 | 113 | return convertView; 114 | } 115 | }); 116 | setContentView(lv); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/dialog/DialogTemplate.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.dialog; 2 | 3 | import android.app.AlertDialog; 4 | import android.app.Dialog; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.v4.app.DialogFragment; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | 11 | import com.oceancx.androidlib.R; 12 | 13 | 14 | /** 15 | * Created by oceancx on 16/1/27. 16 | */ 17 | public class DialogTemplate extends DialogFragment { 18 | 19 | public static DialogTemplate newInstance() { 20 | DialogTemplate fragment = new DialogTemplate(); 21 | Bundle bundle = new Bundle(); 22 | 23 | fragment.setArguments(bundle);//把参数传递给该DialogFragment 24 | return fragment; 25 | } 26 | 27 | @NonNull 28 | @Override 29 | public Dialog onCreateDialog(Bundle savedInstanceState) { 30 | Bundle args = getArguments(); 31 | try { 32 | 33 | } catch (NullPointerException e) { 34 | throw new IllegalArgumentException("传递参数失败"); 35 | } 36 | 37 | 38 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 39 | View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_template, null); 40 | builder.setView(view); 41 | 42 | init(view); 43 | 44 | Dialog dialog = builder.create(); 45 | setStyle(STYLE_NO_FRAME, 0); 46 | 47 | return dialog; 48 | } 49 | 50 | private void init(View view) { 51 | 52 | } 53 | 54 | public interface DialogTemplateImp { 55 | 56 | void onEvent(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/dialog/FgHelper.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.dialog; 2 | 3 | import android.support.v4.app.DialogFragment; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentTransaction; 6 | import android.support.v7.app.AppCompatActivity; 7 | 8 | /** 9 | * Created by oceancx on 15/12/30. 10 | */ 11 | public class FgHelper { 12 | 13 | public static void showDialogFragment(DialogFragment dialogFragment, String tag, AppCompatActivity mAty) { 14 | FragmentTransaction mFragTransaction = mAty.getSupportFragmentManager().beginTransaction(); 15 | Fragment fragment = mAty.getSupportFragmentManager().findFragmentByTag(tag); 16 | if (fragment != null) { 17 | //为了不重复显示dialog,在显示对话框之前移除正在显示的对话框 18 | mFragTransaction.remove(fragment); 19 | } 20 | dialogFragment.show(mFragTransaction, tag); 21 | } 22 | 23 | 24 | public static Fragment findFragmentByTag(AppCompatActivity mAty, String tag) { 25 | Fragment fragment = mAty.getSupportFragmentManager().findFragmentByTag(tag); 26 | return fragment; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/main/CheckBoxActivity.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.main; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | import com.oceancx.androidlib.R; 8 | 9 | /** 10 | * Created by oceancx on 16/2/3. 11 | */ 12 | public class CheckBoxActivity extends AppCompatActivity { 13 | @Override 14 | protected void onCreate(@Nullable Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.checkbox_activity); 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/main/MediaPlayerActivity.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.main; 2 | 3 | import android.media.AudioManager; 4 | import android.media.MediaPlayer; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.os.Environment; 8 | import android.support.annotation.Nullable; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.view.View; 11 | import android.widget.Button; 12 | 13 | import com.oceancx.androidlib.R; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | 18 | 19 | /** 20 | * Created by oceancx on 16/2/27. 21 | */ 22 | public class MediaPlayerActivity extends AppCompatActivity implements View.OnClickListener { 23 | 24 | 25 | MediaPlayer mMediaPlayer; 26 | String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "1.mp3"; 27 | Button play_bt, pause_bt, stop_bt; 28 | private int state = STATE_PLAY; 29 | private static final int STATE_PLAY = 1; 30 | private static final int STATE_PAUSE = 2; 31 | private static final int STATE_STOP = 3; 32 | 33 | 34 | @Override 35 | protected void onCreate(@Nullable Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | setContentView(R.layout.media_player_activity); 38 | play_bt = (Button) findViewById(R.id.play_bt); 39 | pause_bt = (Button) findViewById(R.id.pause_bt); 40 | stop_bt = (Button) findViewById(R.id.stop_bt); 41 | 42 | play_bt.setOnClickListener(this); 43 | pause_bt.setOnClickListener(this); 44 | stop_bt.setOnClickListener(this); 45 | 46 | mMediaPlayer = new MediaPlayer(); 47 | } 48 | 49 | @Override 50 | protected void onDestroy() { 51 | super.onDestroy(); 52 | mMediaPlayer.release(); 53 | } 54 | 55 | @Override 56 | public void onClick(View v) { 57 | 58 | switch (v.getId()) { 59 | case R.id.play_bt: { 60 | try { 61 | 62 | if (state == STATE_PAUSE || state == STATE_STOP) { 63 | mMediaPlayer.start(); 64 | } else { 65 | mMediaPlayer.setDataSource(this, Uri.parse(path)); 66 | mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 67 | mMediaPlayer.prepare(); 68 | mMediaPlayer.start(); 69 | } 70 | state = STATE_PLAY; 71 | } catch (IOException e) { 72 | e.printStackTrace(); 73 | } 74 | break; 75 | } 76 | case R.id.pause_bt: { 77 | mMediaPlayer.pause(); 78 | state = STATE_PAUSE; 79 | 80 | break; 81 | } 82 | case R.id.stop_bt: { 83 | mMediaPlayer.stop(); 84 | mMediaPlayer.reset(); 85 | state = STATE_STOP; 86 | 87 | break; 88 | } 89 | 90 | } 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/main/PullToRefreshAndLoadMoreActivity.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.main; 2 | 3 | import android.os.AsyncTask; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.TextView; 12 | 13 | import com.oceancx.androidlib.R; 14 | import com.oceancx.pulltorefreshandloadmore.PullToFreshAndLordMoreLayout; 15 | 16 | 17 | /** 18 | * Created by oceancx on 16/2/20. 19 | */ 20 | public class PullToRefreshAndLoadMoreActivity extends AppCompatActivity { 21 | 22 | RecyclerView rv; 23 | 24 | 25 | PullToFreshAndLordMoreLayout pullToFreshAndLordMoreLayout; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.pull_to_fresh_and_loadmore_activity); 31 | 32 | pullToFreshAndLordMoreLayout = (PullToFreshAndLordMoreLayout) findViewById(R.id.pull_to_refresh); 33 | pullToFreshAndLordMoreLayout.setRefreshAndLoadMoreListener(new PullToFreshAndLordMoreLayout.RefreshAndLoadMoreListener() { 34 | @Override 35 | public void onLoadMore() { 36 | 37 | } 38 | 39 | @Override 40 | public void onRefresh() { 41 | 42 | /** 43 | * on Refresh 44 | */ 45 | new AsyncTask() { 46 | 47 | @Override 48 | protected Void doInBackground(Void... params) { 49 | try { 50 | Thread.sleep(1000); 51 | } catch (InterruptedException e) { 52 | e.printStackTrace(); 53 | } 54 | return null; 55 | } 56 | 57 | @Override 58 | protected void onPostExecute(Void aVoid) { 59 | super.onPostExecute(aVoid); 60 | pullToFreshAndLordMoreLayout.onFinishRefresh(); 61 | } 62 | }.execute(); 63 | } 64 | 65 | @Override 66 | public void onLoadMoreComplete() { 67 | 68 | } 69 | 70 | @Override 71 | public void onRefreshComplete() { 72 | 73 | } 74 | }); 75 | 76 | // pull_to_refresh_control_bt = (Button) findViewById(R.id.pull_to_refresh_control_bt); 77 | 78 | 79 | rv = (RecyclerView) findViewById(R.id.ryc_views); 80 | rv.setLayoutManager(new LinearLayoutManager(this)); 81 | rv.setAdapter(new RecyclerAdapter()); 82 | } 83 | 84 | public class RecyclerAdapter extends RecyclerView.Adapter { 85 | String[] items = {"Today My Life Begins", "Talking To The Moon ", "Count On Me ", "Turn Around", "Lost", "Rest", "Take The Long Way Home", "Lights", "Faded", "Watching Her Move", "No Promises", "Falling Slowly (From )", "You're Not Alone", "No Promises", "The Way You Were", "Moving Target", "Someone To Love", "Easy To Love You", "About You Now", "Must Be A Reason Why (featuring J. Pearl)", "Wanna Be Close", "Get Away", "Everything About You", "Lie About Us", "You & I", "Makin' Good Love", "Toast to Love", "Your Body Is The Business", "80 in 30", "You Know What", "Take It Off", "Tik Tok", "Feels Like Rain", "Tik Tok", "Die Young (Remix)", "TiK ToK (Fred Falke Club Remix)", "Chain Reaction", "C U Next Tuesday", "Slow Motion", "Friday Night Bitch Fight"}; 86 | 87 | @Override 88 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 89 | View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false); 90 | return new VH(v); 91 | } 92 | 93 | @Override 94 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 95 | VH vh = (VH) holder; 96 | vh.tv.setText(items[position]); 97 | } 98 | 99 | @Override 100 | public int getItemCount() { 101 | return items.length; 102 | } 103 | 104 | private class VH extends RecyclerView.ViewHolder { 105 | TextView tv; 106 | 107 | public VH(View itemView) { 108 | super(itemView); 109 | tv = (TextView) itemView.findViewById(R.id.tv); 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/main/RangeSeekActivity.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.main; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.Toast; 8 | 9 | import com.oceancx.androidlib.R; 10 | import com.oceancx.rangeseekbar.RangeSeekBar; 11 | 12 | /** 13 | * Created by oceancx on 16/2/2. 14 | */ 15 | public class RangeSeekActivity extends AppCompatActivity { 16 | RangeSeekBar seekBar; 17 | 18 | int state = 0; 19 | 20 | @Override 21 | protected void onCreate(@Nullable Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.range_seekbar_activity); 24 | seekBar = (RangeSeekBar) findViewById(R.id.seekbar); 25 | 26 | } 27 | 28 | 29 | public void onToggleButtonClick(View v) { 30 | if (state == 0) { 31 | Toast.makeText(RangeSeekActivity.this, "state:" + state, Toast.LENGTH_SHORT).show(); 32 | state++; 33 | seekBar.setSeekRange(RangeSeekBar.MODE_TIME, 0, 24 * 60 * 60, 10 * 60 * 60, 20 * 60 * 60); 34 | } else if (state == 1) { 35 | Toast.makeText(RangeSeekActivity.this, "state:" + state, Toast.LENGTH_SHORT).show(); 36 | state++; 37 | seekBar.setSeekRange(RangeSeekBar.MODE_MAX_MIN_VALUE, 9, 200, 10, 20); 38 | } else { 39 | state = 0; 40 | Toast.makeText(RangeSeekActivity.this, "min:" + seekBar.getInitMinValue() + " \t max:" + seekBar.getInitMaxValue(), Toast.LENGTH_SHORT).show(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/popupwindow/FilterGridPw.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.popupwindow; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.util.DisplayMetrics; 6 | import android.view.KeyEvent; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.Button; 11 | import android.widget.CheckBox; 12 | import android.widget.CompoundButton; 13 | import android.widget.GridLayout; 14 | import android.widget.PopupWindow; 15 | import android.widget.TextView; 16 | 17 | 18 | import com.oceancx.androidlib.DebugLog; 19 | import com.oceancx.androidlib.R; 20 | 21 | import java.util.ArrayList; 22 | 23 | /** 24 | * Created by oceancx on 15/12/30. 25 | */ 26 | public class FilterGridPw extends PopupWindow implements CompoundButton.OnCheckedChangeListener { 27 | 28 | String tagTitle[] = {"城市", "景点", "酒店", "饭店", "机场", "火车站", "租车公司", "长途汽车站", "购物"}; 29 | 30 | CheckBox outCbx; 31 | 32 | TextView tag_pw_header[]; 33 | int tag_pw_headerIds[] = {R.id.tag_pw_header_01, R.id.tag_pw_header_02}; 34 | 35 | GridLayout tag_pw_grid[]; 36 | 37 | int tag_pw_gridIds[] = {R.id.tag_pw_grid_1, 38 | R.id.tag_pw_grid_2}; 39 | Button tag_pw_bt; 40 | 41 | int maxHeaderAndGrid = 2; 42 | int showCount; 43 | // could be any number,but cant be the same 44 | CheckBox[] no_limit_cbx = new CheckBox[2]; 45 | 46 | public FilterGridPw(Context context, CheckBox outCbx) { 47 | super(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 48 | View contentview = LayoutInflater.from(context).inflate(R.layout.tag_popupwindow, null); 49 | setContentView(contentview); 50 | setTouchable(true); 51 | setFocusable(true); 52 | setOutsideTouchable(true); 53 | this.outCbx = outCbx; 54 | contentview.setOnKeyListener(new View.OnKeyListener() { 55 | @Override 56 | public boolean onKey(View v, int keyCode, KeyEvent event) { 57 | if (keyCode == KeyEvent.KEYCODE_BACK) { 58 | dismiss(); 59 | return true; 60 | } 61 | return false; 62 | } 63 | }); 64 | contentview.setFocusable(true); // 这个很重要 65 | contentview.setFocusableInTouchMode(true); 66 | contentview.setOnClickListener(new View.OnClickListener() { 67 | @Override 68 | public void onClick(View v) { 69 | dismiss(); 70 | } 71 | }); 72 | init(context,outCbx); 73 | } 74 | 75 | private void init(Context context, CheckBox outCbx) { 76 | View view = getContentView(); 77 | 78 | 79 | tag_pw_header = new TextView[maxHeaderAndGrid]; 80 | tag_pw_grid = new GridLayout[maxHeaderAndGrid]; 81 | 82 | 83 | for (int i = 0; i < maxHeaderAndGrid; i++) { 84 | tag_pw_header[i] = (TextView) view.findViewById(tag_pw_headerIds[i]); 85 | tag_pw_grid[i] = (GridLayout) view.findViewById(tag_pw_gridIds[i]); 86 | 87 | } 88 | 89 | tag_pw_bt = (Button) view.findViewById(R.id.tag_pw_bt); 90 | tag_pw_bt.setOnClickListener(new View.OnClickListener() { 91 | @Override 92 | public void onClick(View v) { 93 | /** 94 | * 对outCheck设置tag 95 | */ 96 | } 97 | }); 98 | } 99 | 100 | 101 | 102 | private void initGrid(Context context, GridLayout gridLayout) { 103 | Resources res = context.getResources(); 104 | DisplayMetrics dm = res.getDisplayMetrics(); 105 | int w_screen = dm.widthPixels; 106 | int h_screen = dm.heightPixels; 107 | 108 | DebugLog.e("paleft:" + gridLayout.getPaddingLeft()); 109 | 110 | int marRight = 15*3; 111 | int marBottom = marRight; 112 | int width = marRight; 113 | int row = 0; 114 | int col = 0; 115 | 116 | ArrayList tags =new ArrayList<>(); 117 | 118 | for (String tag : tags) { 119 | CheckBox checkBox = (CheckBox) LayoutInflater.from(context).inflate(R.layout.tag_pw_checkbox, null); 120 | checkBox.setOnCheckedChangeListener(this); 121 | checkBox.setText(tag); 122 | checkBox.setTag(tag+1); 123 | 124 | int spec = View.MeasureSpec.makeMeasureSpec(w_screen, View.MeasureSpec.AT_MOST); 125 | checkBox.measure(spec, spec); 126 | 127 | GridLayout.LayoutParams params = new GridLayout.LayoutParams(); 128 | params.width = GridLayout.LayoutParams.WRAP_CONTENT; 129 | params.height = GridLayout.LayoutParams.WRAP_CONTENT; 130 | params.setMargins(0, 0, marRight, marBottom); 131 | params.rowSpec = GridLayout.spec(row); 132 | params.columnSpec = GridLayout.spec(col++); 133 | width += checkBox.getMeasuredWidth() + marRight; 134 | DebugLog.e("width: " + width); 135 | if (width >= w_screen) { 136 | width = marRight + checkBox.getMeasuredWidth() + marRight; 137 | row++; 138 | col = 0; 139 | params.rowSpec = GridLayout.spec(row); 140 | params.columnSpec = GridLayout.spec(col++); 141 | } 142 | gridLayout.addView(checkBox, params); 143 | 144 | } 145 | } 146 | 147 | private int calModeIndex(int mode) { 148 | int exp = -1; 149 | while (mode != 0) { 150 | mode >>= 1; 151 | exp++; 152 | } 153 | return exp; 154 | } 155 | 156 | 157 | @Override 158 | public void dismiss() { 159 | if (outCbx != null && outCbx.isChecked()) { 160 | outCbx.setTag(null); 161 | outCbx.setChecked(false); 162 | } 163 | super.dismiss(); 164 | } 165 | 166 | 167 | 168 | boolean lockCheck = false; 169 | 170 | @Override 171 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 172 | if (isChecked) { 173 | if (buttonView == no_limit_cbx[0]) { 174 | lockCheck = true; 175 | GridLayout gridLayout = tag_pw_grid[0]; 176 | for (int i = 1; i < gridLayout.getChildCount(); i++) { 177 | CheckBox checkBox = (CheckBox) gridLayout.getChildAt(i); 178 | checkBox.setChecked(false); 179 | } 180 | lockCheck = false; 181 | } else if (buttonView == no_limit_cbx[1]) { 182 | lockCheck = true; 183 | GridLayout gridLayout = tag_pw_grid[1]; 184 | for (int i = 1; i < gridLayout.getChildCount(); i++) { 185 | CheckBox checkBox = (CheckBox) gridLayout.getChildAt(i); 186 | checkBox.setChecked(false); 187 | } 188 | lockCheck = false; 189 | } else { 190 | GridLayout gridLayout = tag_pw_grid[0]; 191 | for (int i = 1; i < gridLayout.getChildCount(); i++) { 192 | CheckBox cbx = (CheckBox) gridLayout.getChildAt(i); 193 | if (buttonView == cbx) { 194 | lockCheck = true; 195 | no_limit_cbx[0].setChecked(false); 196 | lockCheck = false; 197 | break; 198 | } 199 | } 200 | 201 | gridLayout = tag_pw_grid[1]; 202 | for (int i = 1; i < gridLayout.getChildCount(); i++) { 203 | CheckBox cbx = (CheckBox) gridLayout.getChildAt(i); 204 | if (buttonView == cbx) { 205 | lockCheck = true; 206 | no_limit_cbx[1].setChecked(false); 207 | lockCheck = false; 208 | break; 209 | } 210 | } 211 | } 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/popupwindow/FilterLinePw.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.popupwindow; 2 | 3 | import android.content.Context; 4 | import android.view.KeyEvent; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.CheckBox; 9 | import android.widget.PopupWindow; 10 | import android.widget.RadioButton; 11 | import android.widget.RadioGroup; 12 | 13 | import com.oceancx.androidlib.R; 14 | 15 | 16 | /** 17 | * 最简单的PopupWindow 18 | * popupwindow的作用是构造出来s007请求 19 | * 然后通知fg更新列表 20 | * Created by oceancx on 15/12/30. 21 | */ 22 | public class FilterLinePw extends PopupWindow { 23 | 24 | 25 | RadioGroup radioGroup; 26 | CheckBox outCbx; 27 | 28 | // could be any number,but cant be the same 29 | int[] rbtIds = {0, 1, 2}; 30 | 31 | public FilterLinePw(Context context, CheckBox outCbx, String[] items) { 32 | super(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 33 | View contentview = LayoutInflater.from(context).inflate(R.layout.line_popupwindow, null); 34 | setContentView(contentview); 35 | setFocusable(true); 36 | setOutsideTouchable(true); 37 | this.outCbx = outCbx; 38 | contentview.setOnKeyListener(new View.OnKeyListener() { 39 | @Override 40 | public boolean onKey(View v, int keyCode, KeyEvent event) { 41 | if (keyCode == KeyEvent.KEYCODE_BACK) { 42 | dismiss(); 43 | return true; 44 | } 45 | return false; 46 | } 47 | }); 48 | contentview.setFocusable(true); // 这个很重要 49 | contentview.setFocusableInTouchMode(true); 50 | contentview.setOnClickListener(new View.OnClickListener() { 51 | @Override 52 | public void onClick(View v) { 53 | dismiss(); 54 | } 55 | }); 56 | 57 | /** 58 | * 用数据初始化ui 59 | */ 60 | radioGroup = (RadioGroup) contentview.findViewById(R.id.filter_layout1); 61 | radioGroup.clearCheck(); 62 | if (items == null) return; 63 | for (int i = 0; i < items.length; i++) { 64 | 65 | RadioButton radioButton = (RadioButton) LayoutInflater.from(context).inflate(R.layout.line_popupwindow_rbt, null); 66 | radioButton.setId(rbtIds[i]); 67 | radioButton.setText(items[i]); 68 | 69 | radioGroup.addView(radioButton, -1, radioGroup.getLayoutParams()); 70 | 71 | if (items[i].equals(outCbx.getText())) { 72 | outCbx.setTag(i); 73 | radioButton.setChecked(true); 74 | } 75 | 76 | } 77 | radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 78 | @Override 79 | public void onCheckedChanged(RadioGroup group, int checkedId) { 80 | dismiss(); 81 | } 82 | }); 83 | 84 | } 85 | 86 | 87 | @Override 88 | public void dismiss() { 89 | if (outCbx != null && outCbx.isChecked()) { 90 | int id = radioGroup.getCheckedRadioButtonId(); 91 | RadioButton rbt = (RadioButton) radioGroup.findViewById(id); 92 | Integer old_tag = (Integer) outCbx.getTag(); 93 | if (old_tag == null) { 94 | super.dismiss(); 95 | return; 96 | } 97 | if (old_tag != id) { 98 | outCbx.setTag(id); 99 | outCbx.setText(rbt.getText()); 100 | } else { 101 | outCbx.setTag(-1); 102 | } 103 | outCbx.setChecked(false); 104 | } 105 | super.dismiss(); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/popupwindow/PwTemplate.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.popupwindow; 2 | 3 | import android.content.Context; 4 | import android.view.KeyEvent; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.CheckBox; 9 | import android.widget.PopupWindow; 10 | 11 | import com.oceancx.androidlib.R; 12 | 13 | 14 | /** 15 | * Created by oceancx on 16/1/27. 16 | */ 17 | public class PwTemplate extends PopupWindow { 18 | CheckBox outCbx; 19 | 20 | public PwTemplate(Context context, CheckBox outCbx) { 21 | super(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 22 | View contentview = LayoutInflater.from(context).inflate(R.layout.line_popupwindow, null); 23 | setContentView(contentview); 24 | setTouchable(true); 25 | setFocusable(true); 26 | setOutsideTouchable(true); 27 | this.outCbx = outCbx; 28 | contentview.setOnKeyListener(new View.OnKeyListener() { 29 | @Override 30 | public boolean onKey(View v, int keyCode, KeyEvent event) { 31 | if (keyCode == KeyEvent.KEYCODE_BACK) { 32 | dismiss(); 33 | return true; 34 | } 35 | return false; 36 | } 37 | }); 38 | contentview.setFocusable(true); // 这个很重要 39 | contentview.setFocusableInTouchMode(true); 40 | contentview.setOnClickListener(new View.OnClickListener() { 41 | @Override 42 | public void onClick(View v) { 43 | dismiss(); 44 | } 45 | }); 46 | init(context); 47 | } 48 | 49 | private void init(Context context) { 50 | 51 | } 52 | 53 | public void dismiss() { 54 | if (outCbx != null && outCbx.isChecked()) { 55 | outCbx.setTag(null); 56 | outCbx.setChecked(false); 57 | } 58 | super.dismiss(); 59 | } 60 | 61 | public void dismiss(Object tag) { 62 | if (outCbx != null && outCbx.isChecked()) { 63 | 64 | // TODO: 15/12/31 warnning: the two statement's postion really matters 65 | outCbx.setTag(tag); 66 | // TODO: 15/12/31 67 | outCbx.setChecked(false); 68 | } 69 | super.dismiss(); 70 | } 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/simpleclass/DumbViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.simpleclass; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | 6 | /** 7 | * Created by oceancx on 15/12/16. 8 | */ 9 | public class DumbViewHolder extends RecyclerView.ViewHolder { 10 | public DumbViewHolder(View itemView) { 11 | super(itemView); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/simpleclass/TextWatcherAdapter.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.simpleclass; 2 | 3 | import android.text.Editable; 4 | import android.text.TextWatcher; 5 | 6 | /** 7 | * Created by oceancx on 15/12/23. 8 | */ 9 | public class TextWatcherAdapter implements TextWatcher { 10 | @Override 11 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { 12 | 13 | } 14 | 15 | @Override 16 | public void onTextChanged(CharSequence s, int start, int before, int count) { 17 | 18 | } 19 | 20 | @Override 21 | public void afterTextChanged(Editable s) { 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/utils/CacheHelper.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | 6 | /** 7 | * 缓存帮助类 8 | * 1. 缓存什么要知道 9 | * 2. 读取什么要知道 10 | * Created by oceancx on 15/11/9. 11 | */ 12 | public class CacheHelper { 13 | private SharedPreferences preferences; 14 | private static CacheHelper CACHE; 15 | public static final String FIRSTE_RECTVIEW="firstRecView"; 16 | 17 | 18 | 19 | public CacheHelper(Context context) { 20 | preferences = context.getSharedPreferences("Cache", Context.MODE_PRIVATE); 21 | } 22 | 23 | public static CacheHelper getInstance(Context context) { 24 | if (CACHE == null) 25 | CACHE = new CacheHelper(context); 26 | return CACHE; 27 | } 28 | 29 | public boolean writeCache(String key, String text) { 30 | return preferences.edit().putString(key, text).commit(); 31 | 32 | } 33 | 34 | public String readCache(String key) { 35 | 36 | return preferences.getString(key, null); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/utils/DateUtils.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.utils; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.text.ParseException; 6 | import java.text.SimpleDateFormat; 7 | import java.util.Calendar; 8 | import java.util.Date; 9 | import java.util.Locale; 10 | 11 | 12 | public class DateUtils { 13 | //20151028_18:00 14 | private static SimpleDateFormat formatter_yyyyMMdd_HH_mm = new SimpleDateFormat("yyyyMMdd_HH:mm"); 15 | private static final int HOURS_OF_A_DAY = 24; 16 | private static final int MINUTES_OF_AN_HOUR = 60; 17 | private static final int SECONDS_OF_A_MINUTE = 60; 18 | private static final int SECONDS_OF_A_HOUR = 60 * 60; 19 | private static final int SECONDS_OF_A_DAY = HOURS_OF_A_DAY * MINUTES_OF_AN_HOUR * SECONDS_OF_A_MINUTE; 20 | private static final int TROUSAND = 1000; 21 | 22 | public static final int YEAR = 0; 23 | public static final int MOUNTH = 1; 24 | public static final int DAY = 2; 25 | public static final int HOUR = 3; 26 | public static final int MINUTE = 4; 27 | public static final int SECOND = 5; 28 | private static SimpleDateFormat formatter_yyyyMMdd = new SimpleDateFormat("yyyyMMdd"); 29 | 30 | 31 | 32 | 33 | public static FormatedTime formatTime(String yyyyMMdd_HH_mm) { 34 | try { 35 | Date d = formatter_yyyyMMdd_HH_mm.parse(yyyyMMdd_HH_mm); 36 | Calendar c = Calendar.getInstance(); 37 | c.setTime(d); 38 | FormatedTime t = new FormatedTime(); 39 | t.year = c.get(Calendar.YEAR); 40 | t.month = c.get(Calendar.MONTH) + 1; 41 | t.day = c.get(Calendar.DAY_OF_MONTH); 42 | t.hour = c.get(Calendar.HOUR_OF_DAY); 43 | t.minute = c.get(Calendar.MINUTE); 44 | t.second = c.get(Calendar.SECOND); 45 | return t; 46 | } catch (ParseException e) { 47 | e.printStackTrace(); 48 | } 49 | return null; 50 | } 51 | 52 | 53 | public static FormatedTime formatTime_yyyyMMdd(String yyyyMMdd) { 54 | try { 55 | Date d = formatter_yyyyMMdd.parse(yyyyMMdd); 56 | Calendar c = Calendar.getInstance(); 57 | c.setTime(d); 58 | FormatedTime t = new FormatedTime(); 59 | t.year = c.get(Calendar.YEAR); 60 | t.month = c.get(Calendar.MONTH) + 1; 61 | t.day = c.get(Calendar.DAY_OF_MONTH); 62 | return t; 63 | } catch (ParseException e) { 64 | e.printStackTrace(); 65 | } 66 | return null; 67 | } 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/utils/FileHelper.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.utils; 2 | 3 | import android.os.Environment; 4 | 5 | import com.oceancx.androidlib.DebugLog; 6 | 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.File; 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.FileWriter; 12 | import java.io.IOException; 13 | 14 | /** 15 | * Created by oceancx on 15/10/26. 16 | */ 17 | public class FileHelper { 18 | static String env = Environment.getExternalStorageDirectory().getAbsolutePath() + "/"; 19 | 20 | public static String load(String path) { 21 | DebugLog.e("load file:" + path); 22 | try { 23 | FileInputStream fis = new FileInputStream(env + path); 24 | byte[] bytes = new byte[1024]; 25 | int len = 0; 26 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 27 | while ((len = fis.read(bytes)) > 0) { 28 | bos.write(bytes, 0, len); 29 | } 30 | fis.close(); 31 | String route = bos.toString(); 32 | return route; 33 | 34 | } catch (FileNotFoundException e) { 35 | e.printStackTrace(); 36 | } catch (IOException e) { 37 | e.printStackTrace(); 38 | } catch (NumberFormatException e) { 39 | e.printStackTrace(); 40 | } 41 | return null; 42 | } 43 | 44 | public static void delete(String path) { 45 | 46 | if (path == null || path.equals("")) 47 | path = env + "1.txt"; 48 | else 49 | path = env + path; 50 | 51 | File f = new File(path); 52 | if (!f.exists()) { 53 | return; 54 | } else { 55 | f.delete(); 56 | } 57 | } 58 | 59 | public static void save(String path, String text) { 60 | 61 | if (path == null || path.equals("")) 62 | path = env + "1.txt"; 63 | else 64 | path = env + path; 65 | 66 | File f = new File(path); 67 | if (!f.exists()) { 68 | try { 69 | f.createNewFile(); 70 | } catch (IOException e) { 71 | e.printStackTrace(); 72 | } 73 | } else { 74 | f.delete(); 75 | try { 76 | f.createNewFile(); 77 | } catch (IOException e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | FileWriter fw = null; 83 | try { 84 | fw = new FileWriter(f); 85 | 86 | fw.write(text + ""); 87 | fw.close(); 88 | DebugLog.e("FileSave:" + text); 89 | DebugLog.e(path + "-文件保存成功!"); 90 | } catch (IOException e) { 91 | e.printStackTrace(); 92 | } 93 | } 94 | 95 | public static String hash(String str) { 96 | int val = 0; 97 | for (int i = 0; i < str.length(); i++) { 98 | char c = str.charAt(i); 99 | val += c; 100 | } 101 | return String.valueOf(val); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/utils/FormatedTime.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.utils; 2 | 3 | /** 4 | * Created by oceancx on 15/10/21. 5 | */ 6 | public class FormatedTime { 7 | public int year; 8 | public int month; 9 | public int day; 10 | public int hour; 11 | public int minute; 12 | public int second; 13 | 14 | 15 | private String completeTo2digits(int field) { 16 | if (field > 99 || field < 0) throw new IllegalArgumentException("参数不能超过100"); 17 | if (field < 10) { 18 | return "0" + field; 19 | } else 20 | return field + ""; 21 | } 22 | 23 | public String getYear() { 24 | 25 | return completeTo2digits(year); 26 | } 27 | 28 | public String getMonth() { 29 | return completeTo2digits(month); 30 | } 31 | 32 | public String getDay() { 33 | return completeTo2digits(day); 34 | } 35 | 36 | public String getHour() { 37 | return completeTo2digits(hour); 38 | } 39 | 40 | public String getMinute() { 41 | return completeTo2digits(minute); 42 | } 43 | 44 | public String getSecond() { 45 | return completeTo2digits(second); 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "FormatedTime{" + 51 | "year=" + year + 52 | ", month=" + month + 53 | ", day=" + day + 54 | ", hour=" + hour + 55 | ", minute=" + minute + 56 | ", second=" + second + 57 | '}'; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/utils/MeasureUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014 Wireless Designs, LLC 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | package com.oceancx.androidlib.utils; 24 | 25 | import android.view.View; 26 | 27 | public class MeasureUtils { 28 | 29 | /** 30 | * Utility to return a view's standard measurement. Uses the 31 | * supplied size when constraints are given. Attempts to 32 | * hold to the desired size unless it conflicts with provided 33 | * constraints. 34 | * 35 | * @param measureSpec Constraints imposed by the parent 36 | * @param contentSize Desired size for the view 37 | * @return The size the view should be. 38 | */ 39 | public static int getMeasurement(int measureSpec, int contentSize) { 40 | int specMode = View.MeasureSpec.getMode(measureSpec); 41 | int specSize = View.MeasureSpec.getSize(measureSpec); 42 | int resultSize = 0; 43 | switch (specMode) { 44 | case View.MeasureSpec.UNSPECIFIED: 45 | //Big as we want to be 46 | resultSize = contentSize; 47 | break; 48 | case View.MeasureSpec.AT_MOST: 49 | //Big as we want to be, up to the spec 50 | resultSize = Math.min(contentSize, specSize); 51 | break; 52 | case View.MeasureSpec.EXACTLY: 53 | //Must be the spec size 54 | resultSize = specSize; 55 | break; 56 | } 57 | 58 | return resultSize; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/widget/AdvancedRadioGroup.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.widget; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.support.annotation.IdRes; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.CompoundButton; 10 | import android.widget.FrameLayout; 11 | import android.widget.RadioButton; 12 | 13 | /** 14 | * 大部分代码是从RadioGroup中复制过来的,可以把这个自定义控件当做一个RadioGroup来使用, 15 | * 只不过它支持孩子节点为ViewGroup,只要孩子里面有RadioButton就可以 16 | * 注意:在RadioGroup中的孩子RadioButton不能设置onCheckedChangeListener 17 | * 只能对RadioGroup设置AdvancedRadioGroupCheckChangedListener 18 | * Created by oceancx on 16/1/7. 19 | */ 20 | public class AdvancedRadioGroup extends FrameLayout { 21 | 22 | public AdvancedRadioGroup(Context context) { 23 | super(context); 24 | init(); 25 | } 26 | 27 | public AdvancedRadioGroup(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | 30 | init(); 31 | } 32 | 33 | public interface AdvancedRadioGroupCheckChangedListener { 34 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked); 35 | } 36 | 37 | 38 | // holds the checked id; the selection is empty by default 39 | private int mCheckedId = -1; 40 | // tracks children radio buttons checked state 41 | private CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener; 42 | // when true, mOnCheckedChangeListener discards events 43 | private boolean mProtectFromCheckedChange = false; 44 | private OnCheckedChangeListener mOnCheckedChangeListener; 45 | private PassThroughHierarchyChangeListener mPassThroughListener; 46 | 47 | 48 | private void init() { 49 | mChildOnCheckedChangeListener = new CheckedStateTracker(); 50 | mPassThroughListener = new PassThroughHierarchyChangeListener(); 51 | super.setOnHierarchyChangeListener(mPassThroughListener); 52 | } 53 | 54 | /** 55 | * {@inheritDoc} 56 | */ 57 | @Override 58 | public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) { 59 | // the user listener is delegated to our pass-through listener 60 | mPassThroughListener.mOnHierarchyChangeListener = listener; 61 | } 62 | 63 | /** 64 | * {@inheritDoc} 65 | */ 66 | @Override 67 | protected void onFinishInflate() { 68 | super.onFinishInflate(); 69 | 70 | // checks the appropriate radio button as requested in the XML file 71 | if (mCheckedId != -1) { 72 | mProtectFromCheckedChange = true; 73 | setCheckedStateForView(mCheckedId, true); 74 | mProtectFromCheckedChange = false; 75 | setCheckedId(mCheckedId); 76 | } 77 | } 78 | 79 | @Override 80 | public void addView(View child, int index, ViewGroup.LayoutParams params) { 81 | 82 | if (child instanceof RadioButton) { 83 | final RadioButton button = (RadioButton) child; 84 | if (button.isChecked()) { 85 | mProtectFromCheckedChange = true; 86 | if (mCheckedId != -1) { 87 | setCheckedStateForView(mCheckedId, false); 88 | } 89 | mProtectFromCheckedChange = false; 90 | setCheckedId(button.getId()); 91 | } 92 | } else if (child instanceof ViewGroup) { 93 | addViewGroup((ViewGroup) child, index, params); 94 | return; 95 | } 96 | super.addView(child, index, params); 97 | } 98 | 99 | 100 | public void addViewGroup(ViewGroup parent, int index, ViewGroup.LayoutParams params) { 101 | 102 | RadioButton child = lookforRadioButton(parent); 103 | 104 | if (child instanceof RadioButton) { 105 | final RadioButton button = (RadioButton) child; 106 | if (button.isChecked()) { 107 | mProtectFromCheckedChange = true; 108 | if (mCheckedId != -1) { 109 | setCheckedStateForView(mCheckedId, false); 110 | } 111 | mProtectFromCheckedChange = false; 112 | setCheckedId(button.getId()); 113 | } 114 | } 115 | super.addView(parent, index, params); 116 | } 117 | 118 | 119 | private RadioButton lookforRadioButton(ViewGroup child) { 120 | if (child instanceof ViewGroup) { 121 | ViewGroup viewGroup = (ViewGroup) child; 122 | for (int i = 0; i < viewGroup.getChildCount(); i++) { 123 | if (viewGroup.getChildAt(i) instanceof RadioButton) { 124 | return (RadioButton) viewGroup.getChildAt(i); 125 | } else { 126 | return lookforRadioButton((ViewGroup) viewGroup.getChildAt(i)); 127 | } 128 | } 129 | } 130 | return null; 131 | } 132 | 133 | 134 | /** 135 | *

Sets the selection to the radio button whose identifier is passed in 136 | * parameter. Using -1 as the selection identifier clears the selection; 137 | * such an operation is equivalent to invoking {@link #clearCheck()}.

138 | * 139 | * @param id the unique id of the radio button to select in this group 140 | * @see #getCheckedRadioButtonId() 141 | * @see #clearCheck() 142 | */ 143 | public void check(@IdRes int id) { 144 | // don't even bother 145 | if (id != -1 && (id == mCheckedId)) { 146 | return; 147 | } 148 | 149 | if (mCheckedId != -1) { 150 | setCheckedStateForView(mCheckedId, false); 151 | } 152 | 153 | if (id != -1) { 154 | setCheckedStateForView(id, true); 155 | } 156 | 157 | setCheckedId(id); 158 | } 159 | 160 | private void setCheckedId(@IdRes int id) { 161 | mCheckedId = id; 162 | if (mOnCheckedChangeListener != null) { 163 | mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId); 164 | } 165 | } 166 | 167 | private void setCheckedStateForView(int viewId, boolean checked) { 168 | View checkedView = findViewById(viewId); 169 | if (checkedView != null && checkedView instanceof RadioButton) { 170 | ((RadioButton) checkedView).setChecked(checked); 171 | } 172 | } 173 | 174 | /** 175 | *

Returns the identifier of the selected radio button in this group. 176 | * Upon empty selection, the returned value is -1.

177 | * 178 | * @return the unique id of the selected radio button in this group 179 | * @attr ref android.R.styleable#RadioGroup_checkedButton 180 | * @see #check(int) 181 | * @see #clearCheck() 182 | */ 183 | @IdRes 184 | public int getCheckedRadioButtonId() { 185 | return mCheckedId; 186 | } 187 | 188 | /** 189 | *

Clears the selection. When the selection is cleared, no radio button 190 | * in this group is selected and {@link #getCheckedRadioButtonId()} returns 191 | * null.

192 | * 193 | * @see #check(int) 194 | * @see #getCheckedRadioButtonId() 195 | */ 196 | public void clearCheck() { 197 | check(-1); 198 | } 199 | 200 | /** 201 | *

Register a callback to be invoked when the checked radio button 202 | * changes in this group.

203 | * 204 | * @param listener the callback to call on checked state change 205 | */ 206 | public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { 207 | mOnCheckedChangeListener = listener; 208 | } 209 | 210 | /** 211 | * {@inheritDoc} 212 | */ 213 | @Override 214 | public LayoutParams generateLayoutParams(AttributeSet attrs) { 215 | return new LayoutParams(getContext(), attrs); 216 | } 217 | 218 | /** 219 | * {@inheritDoc} 220 | */ 221 | @Override 222 | protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 223 | return p instanceof LayoutParams; 224 | } 225 | 226 | @Override 227 | protected LayoutParams generateDefaultLayoutParams() { 228 | return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 229 | } 230 | 231 | @Override 232 | public CharSequence getAccessibilityClassName() { 233 | return AdvancedRadioGroup.class.getName(); 234 | } 235 | 236 | 237 | /** 238 | *

Interface definition for a callback to be invoked when the checked 239 | * radio button changed in this group.

240 | */ 241 | public interface OnCheckedChangeListener { 242 | /** 243 | *

Called when the checked radio button has changed. When the 244 | * selection is cleared, checkedId is -1.

245 | * 246 | * @param group the group in which the checked radio button has changed 247 | * @param checkedId the unique identifier of the newly checked radio button 248 | */ 249 | public void onCheckedChanged(AdvancedRadioGroup group, @IdRes int checkedId); 250 | } 251 | 252 | private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener { 253 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 254 | // prevents from infinite recursion 255 | if (mProtectFromCheckedChange) { 256 | return; 257 | } 258 | 259 | mProtectFromCheckedChange = true; 260 | if (mCheckedId != -1) { 261 | setCheckedStateForView(mCheckedId, false); 262 | } 263 | 264 | mProtectFromCheckedChange = false; 265 | 266 | int id = buttonView.getId(); 267 | setCheckedId(id); 268 | } 269 | } 270 | 271 | /** 272 | *

A pass-through listener acts upon the events and dispatches them 273 | * to another listener. This allows the table layout to set its own internal 274 | * hierarchy change listener without preventing the user to setup his.

275 | */ 276 | public static int id_sand = 12345; 277 | 278 | private class PassThroughHierarchyChangeListener implements 279 | OnHierarchyChangeListener { 280 | private OnHierarchyChangeListener mOnHierarchyChangeListener; 281 | 282 | /** 283 | * {@inheritDoc} 284 | */ 285 | public void onChildViewAdded(View parent, View child) { 286 | if (parent == AdvancedRadioGroup.this && child instanceof RadioButton) { 287 | int id = child.getId(); 288 | // generates an id if it's missing 289 | if (id == View.NO_ID) { 290 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 291 | id = View.generateViewId(); 292 | } 293 | child.setId(id); 294 | } 295 | ((RadioButton) child).setOnCheckedChangeListener( 296 | mChildOnCheckedChangeListener); 297 | } else if (parent == AdvancedRadioGroup.this && child instanceof ViewGroup) { 298 | ViewGroup p = (ViewGroup) child; 299 | RadioButton radioButton = lookforRadioButton(p); 300 | if (radioButton != null) { 301 | int id = radioButton.getId(); 302 | if (id == View.NO_ID) { 303 | id = id_sand++; 304 | } 305 | radioButton.setId(id); 306 | radioButton.setOnCheckedChangeListener(mChildOnCheckedChangeListener); 307 | } 308 | } 309 | 310 | if (mOnHierarchyChangeListener != null) { 311 | mOnHierarchyChangeListener.onChildViewAdded(parent, child); 312 | } 313 | } 314 | 315 | /** 316 | * {@inheritDoc} 317 | */ 318 | public void onChildViewRemoved(View parent, View child) { 319 | if (parent == AdvancedRadioGroup.this && child instanceof RadioButton) { 320 | ((RadioButton) child).setOnCheckedChangeListener(null); 321 | } else if (parent == AdvancedRadioGroup.this && child instanceof ViewGroup) { 322 | RadioButton radioButton = lookforRadioButton((ViewGroup) child); 323 | if (radioButton != null) radioButton.setOnCheckedChangeListener(null); 324 | } 325 | 326 | if (mOnHierarchyChangeListener != null) { 327 | mOnHierarchyChangeListener.onChildViewRemoved(parent, child); 328 | } 329 | } 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/widget/DashedLine.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.DashPathEffect; 7 | import android.graphics.Paint; 8 | import android.graphics.Path; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | 12 | import com.oceancx.androidlib.R; 13 | 14 | 15 | /** 16 | * 虚线自定义视图 17 | * Created by oceancx on 15/12/25. 18 | */ 19 | public class DashedLine extends View { 20 | Paint paint; 21 | Path path; 22 | DashPathEffect pathEffect; 23 | 24 | public DashedLine(Context context) { 25 | this(context, null); 26 | } 27 | 28 | public DashedLine(Context context, AttributeSet attrs) { 29 | this(context, attrs, 0); 30 | 31 | 32 | } 33 | 34 | public DashedLine(Context context, AttributeSet attrs, int defStyleAttr) { 35 | super(context, attrs, defStyleAttr); 36 | pathEffect = new DashPathEffect(new float[]{context.getResources().getDimensionPixelSize(R.dimen._2dp), 37 | context.getResources().getDimensionPixelSize(R.dimen._5dp)}, 0); 38 | paint = new Paint(); 39 | path = new Path(); 40 | } 41 | 42 | 43 | @Override 44 | protected void onDraw(Canvas canvas) { 45 | 46 | paint.reset(); 47 | paint.setStyle(Paint.Style.STROKE); 48 | paint.setStrokeWidth(getMeasuredHeight()); 49 | paint.setColor(Color.rgb(0xbf, 0xc4, 0xd3)); 50 | paint.setAntiAlias(true); 51 | paint.setPathEffect(pathEffect); 52 | path.moveTo(0, 0); 53 | path.lineTo(getMeasuredWidth(), 0); 54 | canvas.drawPath(path, paint); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/widget/DashedOval.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.DashPathEffect; 7 | import android.graphics.Paint; 8 | import android.graphics.Path; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | 12 | import com.oceancx.androidlib.R; 13 | 14 | 15 | /** 16 | * Created by oceancx on 15/12/25. 17 | */ 18 | public class DashedOval extends View { 19 | Paint paint; 20 | Path path; 21 | DashPathEffect pathEffect; 22 | 23 | public DashedOval(Context context) { 24 | super(context); 25 | } 26 | 27 | public DashedOval(Context context, AttributeSet attrs) { 28 | super(context, attrs); 29 | 30 | pathEffect = new DashPathEffect(new float[]{context.getResources().getDimensionPixelSize(R.dimen._2dp), 31 | context.getResources().getDimensionPixelSize(R.dimen._5dp)}, 0); 32 | paint = new Paint(); 33 | path = new Path(); 34 | 35 | } 36 | 37 | public DashedOval(Context context, AttributeSet attrs, int defStyleAttr) { 38 | super(context, attrs, defStyleAttr); 39 | } 40 | 41 | 42 | @Override 43 | protected void onDraw(Canvas canvas) { 44 | 45 | paint.reset(); 46 | paint.setStyle(Paint.Style.STROKE); 47 | paint.setStrokeWidth(getMeasuredHeight()); 48 | paint.setColor(Color.rgb(0xbf, 0xc4, 0xd3)); 49 | paint.setAntiAlias(true); 50 | paint.setPathEffect(pathEffect); 51 | path.moveTo(0, 0); 52 | canvas.drawPath(path, paint); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/widget/ExpandableListViewForScrollView.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.widget; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.ExpandableListView; 6 | 7 | /** 8 | * 可以放在NestedScrollView中,这样就可以在CoordinatorLayout中联动了 9 | * Created by oceancx on 15/12/26. 10 | */ 11 | public class ExpandableListViewForScrollView extends ExpandableListView { 12 | 13 | 14 | public ExpandableListViewForScrollView(Context context) { 15 | super(context); 16 | } 17 | 18 | public ExpandableListViewForScrollView(Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | } 21 | 22 | public ExpandableListViewForScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 23 | super(context, attrs, defStyleAttr); 24 | } 25 | 26 | @Override 27 | /** 28 | * 重写该方法,达到使ListView适应ScrollView的效果 29 | */ 30 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 31 | int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, 32 | MeasureSpec.AT_MOST); 33 | super.onMeasure(widthMeasureSpec, expandSpec); 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/widget/FrameLayoutCheckBox.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | import android.util.AttributeSet; 6 | import android.view.TouchDelegate; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.CheckBox; 10 | import android.widget.CompoundButton; 11 | import android.widget.FrameLayout; 12 | 13 | import java.util.ArrayList; 14 | 15 | /** 16 | * 对里面的CompoundButton(RadioButton/CheckBox)设置了TouchDelegate,用来扩大(RadioButton/CheckBox)的点击区域 17 | * Created by oceancx on 15/12/26. 18 | */ 19 | public class FrameLayoutCheckBox extends FrameLayout { 20 | CompoundButton cbx; 21 | 22 | public FrameLayoutCheckBox(Context context) { 23 | super(context); 24 | } 25 | 26 | public FrameLayoutCheckBox(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | public FrameLayoutCheckBox(Context context, AttributeSet attrs, int defStyleAttr) { 31 | super(context, attrs, defStyleAttr); 32 | } 33 | 34 | private CheckBox findCheckBox(View view) { 35 | //无递归广度优先遍历寻找CheckBox - -!我只是想重温一下C 36 | ArrayList views = new ArrayList<>(); 37 | views.add(view); 38 | while (!views.isEmpty()) { 39 | View c = views.remove(0); 40 | if (c instanceof CheckBox) { 41 | return (CheckBox) c; 42 | } else if (c instanceof ViewGroup) { 43 | ViewGroup fa = (ViewGroup) c; 44 | for (int i = 0; i < fa.getChildCount(); i++) { 45 | views.add(fa.getChildAt(i)); 46 | } 47 | } 48 | } 49 | return null; 50 | } 51 | 52 | @Override 53 | protected void onFinishInflate() { 54 | super.onFinishInflate(); 55 | if (getChildCount() > 0) { 56 | View child = findCheckBox(this); 57 | if (child instanceof CompoundButton) cbx = (CompoundButton) child; 58 | } 59 | } 60 | 61 | @Override 62 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 63 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 64 | if (cbx != null) { 65 | Rect bounds = new Rect(getPaddingLeft(), getPaddingTop(), getPaddingLeft() + getMeasuredWidth() + getPaddingRight(), getPaddingTop() + getMeasuredHeight() + getPaddingBottom()); 66 | TouchDelegate delegate = new TouchDelegate(bounds, cbx); 67 | setTouchDelegate(delegate); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/widget/PullToRefreshRecyclerView.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.widget; 2 | 3 | /** 4 | * 依赖于PullToRefreshLibrary 5 | * 让RecyclerView支持下拉刷新和上拉加载更多 6 | * Created by oceancx on 16/1/21. 7 | */ 8 | public class PullToRefreshRecyclerView{ 9 | //extends PullToRefreshBase { 10 | // 11 | // @Override 12 | // public Orientation getPullToRefreshScrollDirection() { 13 | // return Orientation.VERTICAL; 14 | // } 15 | 16 | // @Override 17 | // protected RecyclerView createRefreshableView(Context context, AttributeSet attrs) { 18 | // 19 | // RecyclerView recyclerView = new RecyclerView(context, attrs); 20 | // recyclerView.setId(R.id.ryc_views); 21 | // return recyclerView; 22 | // } 23 | 24 | // protected boolean isReadyForPullEnd() { 25 | // try { 26 | // RecyclerView mRefreshableView = getRefreshableView(); 27 | // int checkPos = mRefreshableView.getAdapter().getItemCount() - 1; 28 | // 29 | // View mLastChild = mRefreshableView.getChildAt(mRefreshableView.getChildCount() - 1); 30 | // int rvPos = mRefreshableView.getChildAdapterPosition(mLastChild); 31 | // // 当且仅当第一个可视节点==0 切其top==0的时候 此时rv到达顶部 32 | // if (rvPos == checkPos && mLastChild.getBottom() - mLastChild.getTop() == mLastChild.getMeasuredHeight() && mLastChild.getBottom() == mRefreshableView.getBottom()) { 33 | // return true; 34 | // } 35 | // } catch (NullPointerException e) { 36 | // e.printStackTrace(); 37 | // } 38 | // return false; 39 | // } 40 | // 41 | // protected boolean isReadyForPullStart() { 42 | // try { 43 | // int checkPos = 0; 44 | // RecyclerView mRefreshableView = getRefreshableView(); 45 | // View mFirstChild = mRefreshableView.getChildAt(0); 46 | // int rvPos = mRefreshableView.getChildLayoutPosition(mFirstChild); 47 | // // 当且仅当第一个可视节点==0 切其top==0的时候 此时rv到达顶部 48 | // if (rvPos == checkPos && mFirstChild.getTop() == mRefreshableView.getPaddingTop()) { 49 | // return true; 50 | // } 51 | // } catch (NullPointerException e) { 52 | // e.printStackTrace(); 53 | // } 54 | // return false; 55 | // } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/oceancx/androidlib/widget/TranslusantView.java: -------------------------------------------------------------------------------- 1 | package com.oceancx.androidlib.widget; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.MotionEvent; 6 | import android.widget.FrameLayout; 7 | 8 | /** 9 | * 用来做遮罩,看似简单,却很实用 10 | * Created by oceancx on 15/12/11. 11 | */ 12 | public class TranslusantView extends FrameLayout { 13 | 14 | public TranslusantView(Context context) { 15 | super(context); 16 | } 17 | 18 | public TranslusantView(Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | } 21 | 22 | public TranslusantView(Context context, AttributeSet attrs, int defStyleAttr) { 23 | super(context, attrs, defStyleAttr); 24 | } 25 | 26 | @Override 27 | public boolean onTouchEvent(MotionEvent event) { 28 | 29 | return super.onTouchEvent(event); 30 | } 31 | 32 | 33 | @Override 34 | public boolean onInterceptTouchEvent(MotionEvent ev) { 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_10.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_11.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_12.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_4.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_5.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_6.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_7.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_8.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/loading_50x50_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goceancx/AndroidLib/21bb547a08426a8a3743c5cabaf2ff391b5d90cb/app/src/main/res/drawable-mdpi/loading_50x50_9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/cbx_filter_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/cbx_tag_text_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/dis_ripple.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/filter_txt_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/music_pgb_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/pgb_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 |    7 | 10 |    11 | 14 |    15 | 18 |    19 | 22 |    23 | 26 |    27 | 30 | 31 | 34 |    35 | 38 |    39 | 42 |    43 | 46 |    47 | 50 |    51 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_rect_2dp_grey_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_rect_2dp_main_blue.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/round_white_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_circle_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tag_tv_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/checkbox_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 22 | 23 | 32 | 33 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_template.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/divider_grey_e6e7ea.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/line_popupwindow.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/line_popupwindow_cbx.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/src/main/res/layout/line_popupwindow_rbt.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/media_player_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |