├── .gitignore ├── README.md ├── alertview ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── bigkoo │ │ └── alertview │ │ ├── AlertAnimateUtil.java │ │ ├── AlertView.java │ │ ├── AlertViewAdapter.java │ │ ├── OnDismissListener.java │ │ └── OnItemClickListener.java │ └── res │ ├── anim │ ├── fade_in_center.xml │ ├── fade_out_center.xml │ ├── slide_in_bottom.xml │ └── slide_out_bottom.xml │ ├── drawable │ ├── bg_actionsheet_cancel.xml │ ├── bg_actionsheet_header.xml │ ├── bg_alertbutton_bottom.xml │ ├── bg_alertbutton_left.xml │ ├── bg_alertbutton_none.xml │ ├── bg_alertbutton_right.xml │ └── bg_alertview_alert.xml │ ├── layout │ ├── include_alertheader.xml │ ├── item_alertbutton.xml │ ├── layout_alertview.xml │ ├── layout_alertview_actionsheet.xml │ ├── layout_alertview_alert.xml │ ├── layout_alertview_alert_horizontal.xml │ └── layout_alertview_alert_vertical.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── integers.xml │ ├── strings.xml │ └── styles.xml ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── bigkoo │ │ └── alertviewdemo │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── bigkoo │ │ └── alertviewdemo │ │ └── MainActivity.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ ├── activity_main.xml │ └── alertext_form.xml │ ├── menu │ └── menu_main.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── preview └── alertviewdemo.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 | # Eclipse project files 19 | .classpath 20 | .project 21 | 22 | # Android Studio 23 | .idea/ 24 | .gradle 25 | /*/local.properties 26 | /*/out 27 | build 28 | /*/*/production 29 | *.iml 30 | *.iws 31 | *.ipr 32 | *~ 33 | *.swp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Android Gems](http://www.android-gems.com/badge/saiwu-bigkoo/Android-AlertView.svg?branch=master)](http://www.android-gems.com/lib/saiwu-bigkoo/Android-AlertView) 2 | 3 | # Android-AlertView 4 | 仿iOS的AlertViewController 5 | 几乎完美还原iOS 的 AlertViewController ,同时支持Alert和ActionSheet模式,每一个细节都是精雕细琢,并把api封装成懒到极致模式,一行代码就可以进行弹窗. 6 | 7 | ## Demo 8 | ![](https://github.com/saiwu-bigkoo/Android-AlertView/blob/master/preview/alertviewdemo.gif) 9 | 10 | demo是用Module方式依赖,你也可以使用gradle 依赖: 11 | ```java 12 | compile 'com.bigkoo:alertview:1.0.3' 13 | ``` 14 | 15 | ### config in java code 16 | ```java 17 | new AlertView("上传头像", null, "取消", null, 18 | new String[]{"拍照", "从相册中选择"}, 19 | this, AlertView.Style.ActionSheet, new OnItemClickListener(){ 20 | public void onItemClick(Object o,int position){ 21 | Toast.makeText(this, "点击了第" + position + "个", 22 | Toast.LENGTH_SHORT).show(); 23 | } 24 | }).show(); 25 | 26 | //或者builder模式创建 27 | new AlertView.Builder().setContext(context) 28 | .setStyle(AlertView.Style.ActionSheet) 29 | .setTitle("选择操作") 30 | .setMessage(null) 31 | .setCancelText("取消") 32 | .setDestructive("拍照", "从相册中选择") 33 | .setOthers(null) 34 | .setOnItemClickListener(listener) 35 | .build() 36 | .show(); 37 | ``` 38 | ```java 39 | new AlertView("标题", "内容", null, new String[]{"确定"}, null, this, 40 | AlertView.Style.Alert, null).show(); 41 | ``` 42 | 另外还支持窗口界面拓展,更多操作请下载Demo看。 43 | -------------------------------------------------------------------------------- /alertview/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /alertview/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | apply plugin: 'com.jfrog.bintray' 4 | 5 | version = "1.0.3" 6 | 7 | android { 8 | compileSdkVersion 23 9 | buildToolsVersion "23.0.3" 10 | 11 | defaultConfig { 12 | minSdkVersion 9 13 | targetSdkVersion 21 14 | versionCode 1 15 | versionName "1.0" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | 26 | def siteUrl = 'https://github.com/saiwu-bigkoo/Android-AlertView' // #CONFIG# // project homepage 27 | def gitUrl = 'https://github.com/saiwu-bigkoo/Android-AlertView.git' // #CONFIG# // project git 28 | group = "com.bigkoo" 29 | 30 | install { 31 | repositories.mavenInstaller { 32 | // This generates POM.xml with proper parameters 33 | pom { 34 | project{ 35 | packaging 'aar' 36 | name 'AlertView For Android' // #CONFIG# // project title 37 | url siteUrl 38 | // Set your license 39 | licenses { 40 | license { 41 | name 'The Apache Software License, Version 2.0' 42 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 43 | } 44 | } 45 | developers { 46 | developer { 47 | id 'sai' // #CONFIG# // your user id (you can write your nickname) 48 | name 'sai.wu' // #CONFIG# // your user name 49 | email 'sai.wu@bigkoo.com' // #CONFIG# // your email 50 | } 51 | } 52 | scm { 53 | connection gitUrl 54 | developerConnection gitUrl 55 | url siteUrl 56 | } 57 | } 58 | } 59 | } 60 | } 61 | 62 | task sourcesJar(type: Jar) { 63 | from android.sourceSets.main.java.srcDirs 64 | classifier = 'sources' 65 | } 66 | 67 | task javadoc(type: Javadoc) { 68 | source = android.sourceSets.main.java.srcDirs 69 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 70 | } 71 | 72 | task javadocJar(type: Jar, dependsOn: javadoc) { 73 | classifier = 'javadoc' 74 | from javadoc.destinationDir 75 | } 76 | 77 | artifacts { 78 | archives javadocJar 79 | archives sourcesJar 80 | } 81 | 82 | Properties properties = new Properties() 83 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 84 | bintray { 85 | user = properties.getProperty("bintray.user") 86 | key = properties.getProperty("bintray.apikey") 87 | configurations = ['archives'] 88 | pkg { 89 | repo = "maven" 90 | name = "AlertView" // #CONFIG# project name in jcenter 91 | websiteUrl = siteUrl 92 | vcsUrl = gitUrl 93 | licenses = ["Apache-2.0"] 94 | publish = true 95 | } 96 | } -------------------------------------------------------------------------------- /alertview/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/Sai/Documents/software/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 | -------------------------------------------------------------------------------- /alertview/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /alertview/src/main/java/com/bigkoo/alertview/AlertAnimateUtil.java: -------------------------------------------------------------------------------- 1 | package com.bigkoo.alertview; 2 | 3 | import android.view.Gravity; 4 | 5 | /** 6 | * Created by Sai on 15/8/9. 7 | */ 8 | public class AlertAnimateUtil { 9 | private static final int INVALID = -1; 10 | /** 11 | * Get default animation resource when not defined by the user 12 | * 13 | * @param gravity the gravity of the dialog 14 | * @param isInAnimation determine if is in or out animation. true when is is 15 | * @return the id of the animation resource 16 | */ 17 | static int getAnimationResource(int gravity, boolean isInAnimation) { 18 | switch (gravity) { 19 | case Gravity.BOTTOM: 20 | return isInAnimation ? R.anim.slide_in_bottom : R.anim.slide_out_bottom; 21 | case Gravity.CENTER: 22 | return isInAnimation ? R.anim.fade_in_center : R.anim.fade_out_center; 23 | } 24 | return INVALID; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /alertview/src/main/java/com/bigkoo/alertview/AlertView.java: -------------------------------------------------------------------------------- 1 | package com.bigkoo.alertview; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Typeface; 6 | import android.view.Gravity; 7 | import android.view.LayoutInflater; 8 | import android.view.MotionEvent; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.view.ViewStub; 12 | import android.view.animation.Animation; 13 | import android.view.animation.AnimationUtils; 14 | import android.widget.AdapterView; 15 | import android.widget.FrameLayout; 16 | import android.widget.LinearLayout; 17 | import android.widget.ListView; 18 | import android.widget.TextView; 19 | 20 | import java.lang.ref.WeakReference; 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | 25 | /** 26 | * Created by Sai on 15/8/9. 27 | * 精仿iOSAlertViewController控件 28 | * 点击取消按钮返回 -1,其他按钮从0开始算 29 | */ 30 | public class AlertView { 31 | public enum Style{ 32 | ActionSheet, 33 | Alert 34 | } 35 | private final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( 36 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM 37 | ); 38 | public static final int HORIZONTAL_BUTTONS_MAXCOUNT = 2; 39 | public static final int CANCELPOSITION = -1;//点击取消按钮返回 -1,其他按钮从0开始算 40 | 41 | private String title; 42 | private String msg; 43 | private String[] destructive; 44 | private String[] others; 45 | private List mDestructive; 46 | private List mOthers; 47 | private String cancel; 48 | private ArrayList mDatas = new ArrayList(); 49 | 50 | private WeakReference contextWeak; 51 | private ViewGroup contentContainer; 52 | private ViewGroup decorView;//activity的根View 53 | private ViewGroup rootView;//AlertView 的 根View 54 | private ViewGroup loAlertHeader;//窗口headerView 55 | 56 | private Style style = Style.Alert; 57 | 58 | private OnDismissListener onDismissListener; 59 | private OnItemClickListener onItemClickListener; 60 | private boolean isShowing; 61 | 62 | private Animation outAnim; 63 | private Animation inAnim; 64 | private int gravity = Gravity.CENTER; 65 | 66 | public AlertView(Builder builder) { 67 | this.contextWeak = new WeakReference<>(builder.context); 68 | this.style = builder.style; 69 | this.title = builder.title; 70 | this.msg = builder.msg; 71 | this.cancel = builder.cancel; 72 | this.destructive = builder.destructive; 73 | this.others = builder.others; 74 | this.onItemClickListener = builder.onItemClickListener; 75 | 76 | initData(title, msg, cancel, destructive, others); 77 | initViews(); 78 | init(); 79 | initEvents(); 80 | } 81 | 82 | public AlertView(String title, String msg, String cancel, String[] destructive, String[] others, Context context, Style style,OnItemClickListener onItemClickListener){ 83 | this.contextWeak = new WeakReference<>(context); 84 | if(style != null)this.style = style; 85 | this.onItemClickListener = onItemClickListener; 86 | 87 | initData(title, msg, cancel, destructive, others); 88 | initViews(); 89 | init(); 90 | initEvents(); 91 | } 92 | 93 | /** 94 | * 获取数据 95 | */ 96 | protected void initData(String title, String msg, String cancel, String[] destructive, String[] others) { 97 | 98 | this.title = title; 99 | this.msg = msg; 100 | if (destructive != null){ 101 | this.mDestructive = Arrays.asList(destructive); 102 | this.mDatas.addAll(mDestructive); 103 | } 104 | if (others != null){ 105 | this.mOthers = Arrays.asList(others); 106 | this.mDatas.addAll(mOthers); 107 | } 108 | if (cancel != null){ 109 | this.cancel = cancel; 110 | if(style == Style.Alert && mDatas.size() < HORIZONTAL_BUTTONS_MAXCOUNT){ 111 | this.mDatas.add(0,cancel); 112 | } 113 | } 114 | 115 | } 116 | protected void initViews(){ 117 | Context context = contextWeak.get(); 118 | if(context == null) return; 119 | LayoutInflater layoutInflater = LayoutInflater.from(context); 120 | decorView = (ViewGroup) ((Activity)context).getWindow().getDecorView().findViewById(android.R.id.content); 121 | rootView = (ViewGroup) layoutInflater.inflate(R.layout.layout_alertview, decorView, false); 122 | rootView.setLayoutParams(new FrameLayout.LayoutParams( 123 | ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT 124 | )); 125 | contentContainer = (ViewGroup) rootView.findViewById(R.id.content_container); 126 | int margin_alert_left_right = 0; 127 | switch (style){ 128 | case ActionSheet: 129 | params.gravity = Gravity.BOTTOM; 130 | margin_alert_left_right = context.getResources().getDimensionPixelSize(R.dimen.margin_actionsheet_left_right); 131 | params.setMargins(margin_alert_left_right,0,margin_alert_left_right,margin_alert_left_right); 132 | contentContainer.setLayoutParams(params); 133 | gravity = Gravity.BOTTOM; 134 | initActionSheetViews(layoutInflater); 135 | break; 136 | case Alert: 137 | params.gravity = Gravity.CENTER; 138 | margin_alert_left_right = context.getResources().getDimensionPixelSize(R.dimen.margin_alert_left_right); 139 | params.setMargins(margin_alert_left_right,0,margin_alert_left_right,0); 140 | contentContainer.setLayoutParams(params); 141 | gravity = Gravity.CENTER; 142 | initAlertViews(layoutInflater); 143 | break; 144 | } 145 | } 146 | protected void initHeaderView(ViewGroup viewGroup){ 147 | loAlertHeader = (ViewGroup) viewGroup.findViewById(R.id.loAlertHeader); 148 | //标题和消息 149 | TextView tvAlertTitle = (TextView) viewGroup.findViewById(R.id.tvAlertTitle); 150 | TextView tvAlertMsg = (TextView) viewGroup.findViewById(R.id.tvAlertMsg); 151 | if(title != null) { 152 | tvAlertTitle.setText(title); 153 | }else{ 154 | tvAlertTitle.setVisibility(View.GONE); 155 | } 156 | if(msg != null) { 157 | tvAlertMsg.setText(msg); 158 | }else{ 159 | tvAlertMsg.setVisibility(View.GONE); 160 | } 161 | } 162 | protected void initListView(){ 163 | Context context = contextWeak.get(); 164 | if(context == null) return; 165 | 166 | ListView alertButtonListView = (ListView) contentContainer.findViewById(R.id.alertButtonListView); 167 | //把cancel作为footerView 168 | if(cancel != null && style == Style.Alert){ 169 | View itemView = LayoutInflater.from(context).inflate(R.layout.item_alertbutton, null); 170 | TextView tvAlert = (TextView) itemView.findViewById(R.id.tvAlert); 171 | tvAlert.setText(cancel); 172 | tvAlert.setClickable(true); 173 | tvAlert.setTypeface(Typeface.DEFAULT_BOLD); 174 | tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_cancel)); 175 | tvAlert.setBackgroundResource(R.drawable.bg_alertbutton_bottom); 176 | tvAlert.setOnClickListener(new OnTextClickListener(CANCELPOSITION)); 177 | alertButtonListView.addFooterView(itemView); 178 | } 179 | AlertViewAdapter adapter = new AlertViewAdapter(mDatas,mDestructive); 180 | alertButtonListView.setAdapter(adapter); 181 | alertButtonListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 182 | @Override 183 | public void onItemClick(AdapterView adapterView, View view, int position, long l) { 184 | if(onItemClickListener != null)onItemClickListener.onItemClick(AlertView.this,position); 185 | dismiss(); 186 | } 187 | }); 188 | } 189 | protected void initActionSheetViews(LayoutInflater layoutInflater) { 190 | ViewGroup viewGroup = (ViewGroup) layoutInflater.inflate(R.layout.layout_alertview_actionsheet,contentContainer); 191 | initHeaderView(viewGroup); 192 | 193 | initListView(); 194 | TextView tvAlertCancel = (TextView) contentContainer.findViewById(R.id.tvAlertCancel); 195 | if(cancel != null){ 196 | tvAlertCancel.setVisibility(View.VISIBLE); 197 | tvAlertCancel.setText(cancel); 198 | } 199 | tvAlertCancel.setOnClickListener(new OnTextClickListener(CANCELPOSITION)); 200 | } 201 | protected void initAlertViews(LayoutInflater layoutInflater) { 202 | Context context = contextWeak.get(); 203 | if(context == null) return; 204 | 205 | ViewGroup viewGroup = (ViewGroup) layoutInflater.inflate(R.layout.layout_alertview_alert, contentContainer); 206 | initHeaderView(viewGroup); 207 | 208 | int position = 0; 209 | //如果总数据小于等于HORIZONTAL_BUTTONS_MAXCOUNT,则是横向button 210 | if(mDatas.size()<=HORIZONTAL_BUTTONS_MAXCOUNT){ 211 | ViewStub viewStub = (ViewStub) contentContainer.findViewById(R.id.viewStubHorizontal); 212 | viewStub.inflate(); 213 | LinearLayout loAlertButtons = (LinearLayout) contentContainer.findViewById(R.id.loAlertButtons); 214 | for (int i = 0; i < mDatas.size(); i ++) { 215 | //如果不是第一个按钮 216 | if (i != 0){ 217 | //添加上按钮之间的分割线 218 | View divier = new View(context); 219 | divier.setBackgroundColor(context.getResources().getColor(R.color.bgColor_divier)); 220 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams((int)context.getResources().getDimension(R.dimen.size_divier), LinearLayout.LayoutParams.MATCH_PARENT); 221 | loAlertButtons.addView(divier,params); 222 | } 223 | View itemView = LayoutInflater.from(context).inflate(R.layout.item_alertbutton, null); 224 | TextView tvAlert = (TextView) itemView.findViewById(R.id.tvAlert); 225 | tvAlert.setClickable(true); 226 | 227 | //设置点击效果 228 | if(mDatas.size() == 1){ 229 | tvAlert.setBackgroundResource(R.drawable.bg_alertbutton_bottom); 230 | } 231 | else if(i == 0){//设置最左边的按钮效果 232 | tvAlert.setBackgroundResource(R.drawable.bg_alertbutton_left); 233 | } 234 | else if(i == mDatas.size() - 1){//设置最右边的按钮效果 235 | tvAlert.setBackgroundResource(R.drawable.bg_alertbutton_right); 236 | } 237 | String data = mDatas.get(i); 238 | tvAlert.setText(data); 239 | 240 | //取消按钮的样式 241 | if (data == cancel){ 242 | tvAlert.setTypeface(Typeface.DEFAULT_BOLD); 243 | tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_cancel)); 244 | tvAlert.setOnClickListener(new OnTextClickListener(CANCELPOSITION)); 245 | position = position - 1; 246 | } 247 | //高亮按钮的样式 248 | else if (mDestructive!= null && mDestructive.contains(data)){ 249 | tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_destructive)); 250 | } 251 | 252 | tvAlert.setOnClickListener(new OnTextClickListener(position)); 253 | position++; 254 | loAlertButtons.addView(itemView,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 255 | LinearLayout.LayoutParams.WRAP_CONTENT, 1)); 256 | } 257 | } 258 | else{ 259 | ViewStub viewStub = (ViewStub) contentContainer.findViewById(R.id.viewStubVertical); 260 | viewStub.inflate(); 261 | initListView(); 262 | } 263 | } 264 | protected void init() { 265 | inAnim = getInAnimation(); 266 | outAnim = getOutAnimation(); 267 | } 268 | protected void initEvents() { 269 | } 270 | public AlertView addExtView(View extView){ 271 | loAlertHeader.addView(extView); 272 | return this; 273 | } 274 | /** 275 | * show的时候调用 276 | * 277 | * @param view 这个View 278 | */ 279 | private void onAttached(View view) { 280 | isShowing = true; 281 | decorView.addView(view); 282 | contentContainer.startAnimation(inAnim); 283 | } 284 | /** 285 | * 添加这个View到Activity的根视图 286 | */ 287 | public void show() { 288 | if (isShowing()) { 289 | return; 290 | } 291 | onAttached(rootView); 292 | } 293 | /** 294 | * 检测该View是不是已经添加到根视图 295 | * 296 | * @return 如果视图已经存在该View返回true 297 | */ 298 | public boolean isShowing() { 299 | return rootView.getParent() != null && isShowing; 300 | } 301 | 302 | public void dismiss() { 303 | //消失动画 304 | outAnim.setAnimationListener(outAnimListener); 305 | contentContainer.startAnimation(outAnim); 306 | } 307 | 308 | public void dismissImmediately() { 309 | decorView.removeView(rootView); 310 | isShowing = false; 311 | if(onDismissListener != null){ 312 | onDismissListener.onDismiss(this); 313 | } 314 | 315 | } 316 | 317 | public Animation getInAnimation() { 318 | Context context = contextWeak.get(); 319 | if(context == null) return null; 320 | 321 | int res = AlertAnimateUtil.getAnimationResource(this.gravity, true); 322 | return AnimationUtils.loadAnimation(context, res); 323 | } 324 | 325 | public Animation getOutAnimation() { 326 | Context context = contextWeak.get(); 327 | if(context == null) return null; 328 | 329 | int res = AlertAnimateUtil.getAnimationResource(this.gravity, false); 330 | return AnimationUtils.loadAnimation(context, res); 331 | } 332 | 333 | public AlertView setOnDismissListener(OnDismissListener onDismissListener) { 334 | this.onDismissListener = onDismissListener; 335 | return this; 336 | } 337 | 338 | class OnTextClickListener implements View.OnClickListener{ 339 | 340 | private int position; 341 | public OnTextClickListener(int position){ 342 | this.position = position; 343 | } 344 | @Override 345 | public void onClick(View view) { 346 | if(onItemClickListener != null)onItemClickListener.onItemClick(AlertView.this,position); 347 | dismiss(); 348 | } 349 | } 350 | private Animation.AnimationListener outAnimListener = new Animation.AnimationListener() { 351 | @Override 352 | public void onAnimationStart(Animation animation) { 353 | 354 | } 355 | 356 | @Override 357 | public void onAnimationEnd(Animation animation) { 358 | dismissImmediately(); 359 | } 360 | 361 | @Override 362 | public void onAnimationRepeat(Animation animation) { 363 | 364 | } 365 | }; 366 | 367 | /** 368 | * 主要用于拓展View的时候有输入框,键盘弹出则设置MarginBottom往上顶,避免输入法挡住界面 369 | */ 370 | public void setMarginBottom(int marginBottom){ 371 | Context context = contextWeak.get(); 372 | if(context == null) return; 373 | 374 | int margin_alert_left_right = context.getResources().getDimensionPixelSize(R.dimen.margin_alert_left_right); 375 | params.setMargins(margin_alert_left_right,0,margin_alert_left_right,marginBottom); 376 | contentContainer.setLayoutParams(params); 377 | } 378 | public AlertView setCancelable(boolean isCancelable) { 379 | View view = rootView.findViewById(R.id.outmost_container); 380 | 381 | if (isCancelable) { 382 | view.setOnTouchListener(onCancelableTouchListener); 383 | } 384 | else{ 385 | view.setOnTouchListener(null); 386 | } 387 | return this; 388 | } 389 | /** 390 | * Called when the user touch on black overlay in order to dismiss the dialog 391 | */ 392 | private final View.OnTouchListener onCancelableTouchListener = new View.OnTouchListener() { 393 | @Override 394 | public boolean onTouch(View v, MotionEvent event) { 395 | if (event.getAction() == MotionEvent.ACTION_DOWN) { 396 | dismiss(); 397 | } 398 | return false; 399 | } 400 | }; 401 | 402 | /** 403 | * Builder for arguments 404 | */ 405 | public static class Builder { 406 | private Context context; 407 | private Style style; 408 | private String title; 409 | private String msg; 410 | private String cancel; 411 | private String[] destructive; 412 | private String[] others; 413 | private OnItemClickListener onItemClickListener; 414 | 415 | public Builder setContext(Context context) { 416 | this.context = context; 417 | return this; 418 | } 419 | 420 | public Builder setStyle(Style style) { 421 | if(style != null) { 422 | this.style = style; 423 | } 424 | return this; 425 | } 426 | 427 | public Builder setTitle(String title) { 428 | this.title = title; 429 | return this; 430 | } 431 | 432 | public Builder setMessage(String msg) { 433 | this.msg = msg; 434 | return this; 435 | } 436 | 437 | public Builder setCancelText(String cancel) { 438 | this.cancel = cancel; 439 | return this; 440 | } 441 | 442 | public Builder setDestructive(String... destructive) { 443 | this.destructive = destructive; 444 | return this; 445 | } 446 | 447 | public Builder setOthers(String[] others) { 448 | this.others = others; 449 | return this; 450 | } 451 | 452 | public Builder setOnItemClickListener(OnItemClickListener onItemClickListener) { 453 | this.onItemClickListener = onItemClickListener; 454 | return this; 455 | } 456 | 457 | public AlertView build() { 458 | return new AlertView(this); 459 | } 460 | } 461 | } 462 | -------------------------------------------------------------------------------- /alertview/src/main/java/com/bigkoo/alertview/AlertViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.bigkoo.alertview; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.TextView; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Created by Sai on 15/8/9. 14 | */ 15 | public class AlertViewAdapter extends BaseAdapter{ 16 | private List mDatas; 17 | private List mDestructive; 18 | public AlertViewAdapter(List datas,List destructive){ 19 | this.mDatas =datas; 20 | this.mDestructive =destructive; 21 | } 22 | @Override 23 | public int getCount() { 24 | return mDatas.size(); 25 | } 26 | 27 | @Override 28 | public Object getItem(int position) { 29 | return mDatas.get(position); 30 | } 31 | 32 | @Override 33 | public long getItemId(int position) { 34 | return position; 35 | } 36 | 37 | @Override 38 | public View getView(int position, View convertView, ViewGroup parent) { 39 | String data= mDatas.get(position); 40 | Holder holder=null; 41 | View view =convertView; 42 | if(view==null){ 43 | LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 44 | view=inflater.inflate(R.layout.item_alertbutton, null); 45 | holder=creatHolder(view); 46 | view.setTag(holder); 47 | } 48 | else{ 49 | holder=(Holder) view.getTag(); 50 | } 51 | holder.UpdateUI(parent.getContext(),data,position); 52 | return view; 53 | } 54 | public Holder creatHolder(View view){ 55 | return new Holder(view); 56 | } 57 | class Holder { 58 | private TextView tvAlert; 59 | 60 | public Holder(View view){ 61 | tvAlert = (TextView) view.findViewById(R.id.tvAlert); 62 | } 63 | public void UpdateUI(Context context,String data,int position){ 64 | tvAlert.setText(data); 65 | if (mDestructive!= null && mDestructive.contains(data)){ 66 | tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_destructive)); 67 | } 68 | else{ 69 | tvAlert.setTextColor(context.getResources().getColor(R.color.textColor_alert_button_others)); 70 | } 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /alertview/src/main/java/com/bigkoo/alertview/OnDismissListener.java: -------------------------------------------------------------------------------- 1 | package com.bigkoo.alertview; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by Sai on 15/8/9. 7 | */ 8 | public interface OnDismissListener { 9 | public void onDismiss(Object o); 10 | } 11 | -------------------------------------------------------------------------------- /alertview/src/main/java/com/bigkoo/alertview/OnItemClickListener.java: -------------------------------------------------------------------------------- 1 | package com.bigkoo.alertview; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by Sai on 15/8/9. 7 | */ 8 | public interface OnItemClickListener { 9 | public void onItemClick(Object o,int position); 10 | } 11 | -------------------------------------------------------------------------------- /alertview/src/main/res/anim/fade_in_center.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /alertview/src/main/res/anim/fade_out_center.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /alertview/src/main/res/anim/slide_in_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /alertview/src/main/res/anim/slide_out_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /alertview/src/main/res/drawable/bg_actionsheet_cancel.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /alertview/src/main/res/drawable/bg_actionsheet_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /alertview/src/main/res/drawable/bg_alertbutton_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /alertview/src/main/res/drawable/bg_alertbutton_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /alertview/src/main/res/drawable/bg_alertbutton_none.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /alertview/src/main/res/drawable/bg_alertbutton_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /alertview/src/main/res/drawable/bg_alertview_alert.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /alertview/src/main/res/layout/include_alertheader.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 24 | -------------------------------------------------------------------------------- /alertview/src/main/res/layout/item_alertbutton.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 16 | -------------------------------------------------------------------------------- /alertview/src/main/res/layout/layout_alertview.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /alertview/src/main/res/layout/layout_alertview_actionsheet.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 21 | 22 | 30 | 39 | 40 | 41 | 53 | -------------------------------------------------------------------------------- /alertview/src/main/res/layout/layout_alertview_alert.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 15 | 20 | -------------------------------------------------------------------------------- /alertview/src/main/res/layout/layout_alertview_alert_horizontal.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alertview/src/main/res/layout/layout_alertview_alert_vertical.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alertview/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #60000000 5 | 6 | #f8f8f8 7 | #f0f0f0 8 | 9 | #000000 10 | #8f8f8f 11 | 12 | #000000 13 | #8f8f8f 14 | 15 | #d7d7db 16 | 17 | #007aff 18 | 19 | #ff3b30 20 | 21 | #007aff 22 | 23 | #EAEAEA 24 | 25 | #ffffff 26 | 27 | 28 | -------------------------------------------------------------------------------- /alertview/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22sp 5 | 14sp 6 | 7 | 60dp 8 | 40dp 9 | 10 | 15sp 11 | 14sp 12 | 13 | 25dp 14 | 14dp 15 | 16 | 40dp 17 | 10dp 18 | 19 | 1dp 20 | 21 | 48dp 22 | 23 | 18sp 24 | 25 | 15px 26 | 27 | 28 | -------------------------------------------------------------------------------- /alertview/src/main/res/values/integers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 300 5 | -------------------------------------------------------------------------------- /alertview/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AlertActivity 3 | 4 | -------------------------------------------------------------------------------- /alertview/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 27 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | 7 | defaultConfig { 8 | applicationId "com.bigkoo.alertviewdemo" 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 | compile project(':alertview') 25 | compile 'com.android.support:appcompat-v7:23.2.0' 26 | 27 | } 28 | -------------------------------------------------------------------------------- /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/Sai/Documents/software/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/bigkoo/alertviewdemo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.bigkoo.alertviewdemo; 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 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/bigkoo/alertviewdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.bigkoo.alertviewdemo; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.view.KeyEvent; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.view.inputmethod.InputMethodManager; 11 | import android.widget.EditText; 12 | import android.widget.Toast; 13 | 14 | import com.bigkoo.alertview.AlertView; 15 | import com.bigkoo.alertview.OnDismissListener; 16 | import com.bigkoo.alertview.OnItemClickListener; 17 | 18 | /** 19 | * 精仿iOSAlertViewController控件Demo 20 | */ 21 | public class MainActivity extends Activity implements OnItemClickListener, OnDismissListener { 22 | 23 | private AlertView mAlertView;//避免创建重复View,先创建View,然后需要的时候show出来,推荐这个做法 24 | private AlertView mAlertViewExt;//窗口拓展例子 25 | private EditText etName;//拓展View内容 26 | private InputMethodManager imm; 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_main); 31 | imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 32 | mAlertView = new AlertView("标题", "内容", "取消", new String[]{"确定"}, null, this, AlertView.Style.Alert, this).setCancelable(true).setOnDismissListener(this); 33 | //拓展窗口 34 | mAlertViewExt = new AlertView("提示", "请完善你的个人资料!", "取消", null, new String[]{"完成"}, this, AlertView.Style.Alert, this); 35 | ViewGroup extView = (ViewGroup) LayoutInflater.from(this).inflate(R.layout.alertext_form,null); 36 | etName = (EditText) extView.findViewById(R.id.etName); 37 | etName.setOnFocusChangeListener(new View.OnFocusChangeListener() { 38 | @Override 39 | public void onFocusChange(View view, boolean focus) { 40 | //输入框出来则往上移动 41 | boolean isOpen=imm.isActive(); 42 | mAlertViewExt.setMarginBottom(isOpen&&focus ? 120 :0); 43 | System.out.println(isOpen); 44 | } 45 | }); 46 | mAlertViewExt.addExtView(extView); 47 | } 48 | 49 | public void alertShow1(View view) { 50 | mAlertView.show(); 51 | } 52 | 53 | public void alertShow2(View view) { 54 | new AlertView("标题", "内容", null, new String[]{"确定"}, null, this, AlertView.Style.Alert, this).show(); 55 | } 56 | 57 | public void alertShow3(View view) { 58 | new AlertView(null, null, null, new String[]{"高亮按钮1", "高亮按钮2", "高亮按钮3"}, 59 | new String[]{"其他按钮1", "其他按钮2", "其他按钮3", "其他按钮4", "其他按钮5", "其他按钮6", 60 | "其他按钮7", "其他按钮8", "其他按钮9", "其他按钮10", "其他按钮11", "其他按钮12"}, 61 | this, AlertView.Style.Alert, this).show(); 62 | } 63 | 64 | public void alertShow4(View view) { 65 | new AlertView("标题", null, "取消", new String[]{"高亮按钮1"}, new String[]{"其他按钮1", "其他按钮2", "其他按钮3"}, this, AlertView.Style.ActionSheet, this).show(); 66 | } 67 | 68 | public void alertShow5(View view) { 69 | new AlertView("标题", "内容", "取消", null, null, this, AlertView.Style.ActionSheet, this).setCancelable(true).show(); 70 | } 71 | 72 | public void alertShow6(View view) { 73 | new AlertView("上传头像", null, "取消", null, 74 | new String[]{"拍照", "从相册中选择"}, 75 | this, AlertView.Style.ActionSheet, this).show(); 76 | } 77 | 78 | public void alertShowExt(View view) { 79 | mAlertViewExt.show(); 80 | } 81 | private void closeKeyboard() { 82 | //关闭软键盘 83 | imm.hideSoftInputFromWindow(etName.getWindowToken(),0); 84 | //恢复位置 85 | mAlertViewExt.setMarginBottom(0); 86 | } 87 | @Override 88 | public void onItemClick(Object o,int position) { 89 | closeKeyboard(); 90 | //判断是否是拓展窗口View,而且点击的是非取消按钮 91 | if(o == mAlertViewExt && position != AlertView.CANCELPOSITION){ 92 | String name = etName.getText().toString(); 93 | if(name.isEmpty()){ 94 | Toast.makeText(this, "啥都没填呢", Toast.LENGTH_SHORT).show(); 95 | } 96 | else{ 97 | Toast.makeText(this, "hello,"+name, Toast.LENGTH_SHORT).show(); 98 | } 99 | 100 | return; 101 | } 102 | Toast.makeText(this, "点击了第" + position + "个", Toast.LENGTH_SHORT).show(); 103 | } 104 | 105 | @Override 106 | public void onDismiss(Object o) { 107 | closeKeyboard(); 108 | Toast.makeText(this, "消失了", Toast.LENGTH_SHORT).show(); 109 | } 110 | @Override 111 | public boolean onKeyDown(int keyCode, KeyEvent event) 112 | { 113 | if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) 114 | { 115 | if(mAlertView!=null && mAlertView.isShowing()){ 116 | mAlertView.dismiss(); 117 | return false; 118 | } 119 | } 120 | 121 | return super.onKeyDown(keyCode, event); 122 | 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saiwu-bigkoo/Android-AlertView/c6f7b59ca7b2994b034871ca1e76a70bfe85e768/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saiwu-bigkoo/Android-AlertView/c6f7b59ca7b2994b034871ca1e76a70bfe85e768/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saiwu-bigkoo/Android-AlertView/c6f7b59ca7b2994b034871ca1e76a70bfe85e768/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saiwu-bigkoo/Android-AlertView/c6f7b59ca7b2994b034871ca1e76a70bfe85e768/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 |