├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── cjj │ │ └── buttomsheetdemo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── cjj │ │ │ └── buttomsheetdemo │ │ │ ├── BeautifulBottomSheetActivity.java │ │ │ ├── BottomSheetDialogActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── NestedScrollViewActivity.java │ │ │ └── RecyclerViewActivity.java │ └── res │ │ ├── drawable │ │ ├── a5.jpg │ │ ├── a6.jpg │ │ ├── mingren1.jpg │ │ └── mingren2.jpg │ │ ├── layout │ │ ├── acitivity_rv.xml │ │ ├── activity_beautiful.xml │ │ ├── activity_dialog.xml │ │ ├── activity_main.xml │ │ ├── activity_ns.xml │ │ ├── content_main.xml │ │ ├── dialog_layout.xml │ │ ├── item_beau.xml │ │ └── list_item.xml │ │ ├── menu │ │ └── menu_main.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-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── cjj │ └── buttomsheetdemo │ └── ExampleUnitTest.java ├── build.gradle ├── gif ├── bs1.gif ├── bs12.gif └── dialog.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.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 | ButtomSheetDemo -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BottomSheets 2 | ======================= 3 | 如果使用上遇到坑,点击链接加入群【GitHub小伙伴交流群'''】:http://jq.qq.com/?_wv=1027&k=27lxYHB''' ,群号:477826523 帮你搞定一切bug... 4 | 5 | Android Support Library 23.2里的 Design Support Library新加了一个Bottom Sheets控件,一个底部表,就是我们经常在分享或者地图、音乐等app看到的效果 6 | 7 | 8 | 9 | 10 | 昨天晚上Support Library 23.2包还没能更新,官方视频就已经透露出了,[视频地址](https://youtu.be/7E2lNBM38IE?list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX),从视频看出Support Library 23.2包新增了: 11 | 12 | * 1. Support Vector Drawables and Animated Vector Drawables 13 | * 2. AppCompat DayNight theme 14 | * 3. Design Support Library: Bottom Sheets 15 | * 4. Support v4: MediaBrowserServiceCompat 16 | * 5. RecyclerView 17 | * 6. Custom Tabs 18 | * 7. Leanback for Android TV 19 | 20 | 具体可以上官网博客看看。 21 | 22 | 这篇文章我给大家说说BottomSheetBehavior的使用及注意的地方 23 | 24 | ##Usage 25 | ###(1)在布局文件xml中 26 | ```xml 27 | 28 | 36 | 37 | 45 | 46 | 47 | 48 | 49 | ``` 50 | ###(2)在java代码中 51 | ```java 52 | @Override 53 | protected void onCreate(Bundle savedInstanceState) { 54 | super.onCreate(savedInstanceState); 55 | setContentView(R.layout.activity_ns); 56 | 57 | // The View with the BottomSheetBehavior 58 | CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.cl); 59 | View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet); 60 | final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet); 61 | behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 62 | @Override 63 | public void onStateChanged(@NonNull View bottomSheet, int newState) { 64 | //这里是bottomSheet 状态的改变回调 65 | } 66 | 67 | @Override 68 | public void onSlide(@NonNull View bottomSheet, float slideOffset) { 69 | //这里是拖拽中的回调,根据slideOffset可以做一些动画 70 | } 71 | }); 72 | } 73 | ``` 74 | 75 | 其实也挺简单的,我来解释一下。通过附加一个BottomSheetBehavior 给CoordinatorLayout的子视图,上文xml中的是NestedScrollView(adding app:layout_behavior = " android.support.design.widget.BottomSheetBehavior”),当然,RecyclerView也是可以的。如果需要BottomSheet View可以保持滚动,需要支持 nested scrolling (例如: NestedScrollView, RecyclerView, or ListView/ScrollView on API 21+). 76 | 77 | ```xml 78 | app:behavior_hideable="true" 79 | app:behavior_peekHeight="50dp" 80 | ``` 81 | 这两个属性我说说,peekHeight是当Bottom Sheets关闭的时候,底部下表我们能看到的高度,hideable 是当我们拖拽下拉的时候,bottom sheet是否能全部隐藏。 82 | 如果你需要监听Bottom Sheets回调的状态,可以通过setBottomSheetCallback来实现,onSlide方法是拖拽中的回调,根据slideOffset可以做一些动画 83 | onStateChanged方法可以监听到状态的改变,总共有5种 84 | 85 | * STATE_COLLAPSED: 关闭Bottom Sheets,显示peekHeight的高度,默认是0 86 | * STATE_DRAGGING: 用户拖拽Bottom Sheets时的状态 87 | * STATE_SETTLING: 当Bottom Sheets view摆放时的状态。 88 | * STATE_EXPANDED: 当Bottom Sheets 展开的状态 89 | * STATE_HIDDEN: 当Bottom Sheets 隐藏的状态 90 | 91 | 我也简单的写了BottomSheetBehavior和BottomSheetDialog的demo,你可以看我源码是怎么用的 92 | 93 | 94 | 95 | 96 | 使用就这些了,接下来我们来讲讲该注意的地方,应该说怎样更好的使用它。 97 | 98 | ###(1)关闭Bottom Sheets的行为 99 | 可以通过下图的形式,拖拽、点击bottom sheet之外的地方和通过‘x’按钮 100 | 101 | 102 | 103 | 104 | 105 | ###(2)合适的视图设计 106 | 107 | 108 | 109 | 110 | 上图你可明显的看到第二幅这种设计是不合适的,空白太多,不美观,对吧! 111 | 112 | 113 | 114 | 115 | 如果Bottom Sheets 展开或者上拉覆盖了ActionBar or ToolBar 这种方式也是不合适的. 116 | 117 | ###(3)尺寸的设计 118 | 为了符合Material Design 设计,我们对尺寸有严格的要求,当然,你想随意我也阻止不了 119 | 120 | 121 | 122 | 123 | 124 | 我想说的就这些了,如果还有补充,欢迎PR! 125 | 126 | 又写了一篇:[BottomSheets源码解析](https://github.com/android-cjj/SourceAnalysis/blob/master/README.md) 127 | 128 | 129 | 130 | 关于我 131 | --------------------- 132 | 133 | Github:[Android-CJJ](https://github.com/android-cjj)------能 follow 下我就更好了 134 | 135 | 微博:[Android_CJJ](http://weibo.com/chenjijun2011/)-------能 关注 下我就更好了 136 | 137 | GitHub小伙伴交流群'' 477826523,很难进的哦! 138 | 139 | 140 | 141 | License 142 | ======= 143 | 144 | The MIT License (MIT) 145 | 146 | Copyright (c) 2015 android-cjj 147 | 148 | Permission is hereby granted, free of charge, to any person obtaining a copy 149 | of this software and associated documentation files (the "Software"), to deal 150 | in the Software without restriction, including without limitation the rights 151 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 152 | copies of the Software, and to permit persons to whom the Software is 153 | furnished to do so, subject to the following conditions: 154 | 155 | The above copyright notice and this permission notice shall be included in all 156 | copies or substantial portions of the Software. 157 | 158 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 159 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 160 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 161 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 162 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 163 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 164 | SOFTWARE. 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /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.cjj.buttomsheetdemo" 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(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.2.0' 26 | compile 'com.android.support:design:23.2.0' 27 | compile 'com.android.support:cardview-v7:23.2.0' 28 | } 29 | -------------------------------------------------------------------------------- /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 D:\world\android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/cjj/buttomsheetdemo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.cjj.buttomsheetdemo; 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 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/cjj/buttomsheetdemo/BeautifulBottomSheetActivity.java: -------------------------------------------------------------------------------- 1 | package com.cjj.buttomsheetdemo; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | import android.support.design.widget.BottomSheetBehavior; 9 | import android.support.design.widget.CoordinatorLayout; 10 | import android.support.v4.view.ViewCompat; 11 | import android.support.v7.app.AppCompatActivity; 12 | import android.support.v7.widget.DefaultItemAnimator; 13 | import android.support.v7.widget.LinearLayoutManager; 14 | import android.support.v7.widget.RecyclerView; 15 | import android.view.LayoutInflater; 16 | import android.view.Menu; 17 | import android.view.View; 18 | import android.view.ViewGroup; 19 | import android.widget.ImageView; 20 | import android.widget.TextView; 21 | import android.widget.Toast; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import java.util.Random; 26 | 27 | /** 28 | * Created by cjj on 2016/2/29. 29 | */ 30 | public class BeautifulBottomSheetActivity extends AppCompatActivity { 31 | public BottomSheetBehavior behavior; 32 | public RecyclerView recyclerView; 33 | public View ns_view; 34 | 35 | @Override 36 | protected void onCreate(@Nullable Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | setContentView(R.layout.activity_beautiful); 39 | // The View with the BottomSheetBehavior 40 | ns_view = findViewById(R.id.ns); 41 | recyclerView = (RecyclerView) findViewById(R.id.recyclerview); 42 | LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); 43 | linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); 44 | recyclerView.setLayoutManager(linearLayoutManager); 45 | SimpleStringRecyclerViewAdapter simpleStringRecyclerViewAdapter = new SimpleStringRecyclerViewAdapter(this); 46 | 47 | simpleStringRecyclerViewAdapter.setItemClickListener(new SimpleStringRecyclerViewAdapter.ItemClickListener() { 48 | @Override 49 | public void onItemClick(int pos) { 50 | behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 51 | Toast.makeText(BeautifulBottomSheetActivity.this, "pos--->" + pos, Toast.LENGTH_LONG).show(); 52 | } 53 | }); 54 | recyclerView.setAdapter(simpleStringRecyclerViewAdapter); 55 | recyclerView.setItemAnimator(new DefaultItemAnimator()); 56 | behavior = BottomSheetBehavior.from(ns_view); 57 | behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 58 | @Override 59 | public void onStateChanged(@NonNull View bottomSheet, int newState) { 60 | if(newState == BottomSheetBehavior.STATE_COLLAPSED||newState == BottomSheetBehavior.STATE_HIDDEN){ 61 | // blackView.setBackgroundColor(Color.TRANSPARENT); 62 | } 63 | } 64 | 65 | @Override 66 | public void onSlide(@NonNull View bottomSheet, float slideOffset) { 67 | // React to dragging events 68 | } 69 | }); 70 | 71 | findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() { 72 | @Override 73 | public void onClick(View v) { 74 | behavior.setState(BottomSheetBehavior.STATE_EXPANDED); 75 | } 76 | }); 77 | 78 | 79 | } 80 | 81 | 82 | @Override 83 | public boolean onCreateOptionsMenu(Menu menu) { 84 | getMenuInflater().inflate(R.menu.menu_main, menu); 85 | return true; 86 | } 87 | 88 | 89 | 90 | private List getRandomSublist(String[] array, int amount) { 91 | ArrayList list = new ArrayList<>(amount); 92 | Random random = new Random(); 93 | while (list.size() < amount) { 94 | list.add(array[random.nextInt(array.length)]); 95 | } 96 | return list; 97 | } 98 | 99 | public static class SimpleStringRecyclerViewAdapter 100 | extends RecyclerView.Adapter { 101 | 102 | public ItemClickListener mItemClickListener; 103 | 104 | public void setItemClickListener(ItemClickListener listener) { 105 | mItemClickListener = listener; 106 | } 107 | 108 | public interface ItemClickListener { 109 | public void onItemClick(int pos); 110 | } 111 | 112 | private Context mContext; 113 | 114 | public static class ViewHolder extends RecyclerView.ViewHolder { 115 | 116 | public final ImageView mImageView; 117 | public final TextView mTextView; 118 | 119 | public ViewHolder(View view) { 120 | super(view); 121 | mImageView = (ImageView) view.findViewById(R.id.avatar); 122 | mTextView = (TextView) view.findViewById(R.id.tv); 123 | } 124 | 125 | 126 | } 127 | 128 | public SimpleStringRecyclerViewAdapter(Context context) { 129 | super(); 130 | mContext = context; 131 | } 132 | 133 | @Override 134 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 135 | View view = LayoutInflater.from(parent.getContext()) 136 | .inflate(R.layout.item_beau, parent, false); 137 | return new ViewHolder(view); 138 | } 139 | 140 | @Override 141 | public void onBindViewHolder(final ViewHolder holder, final int position) { 142 | 143 | holder.mTextView.setOnClickListener(new View.OnClickListener() { 144 | @Override 145 | public void onClick(View v) { 146 | // Toast.makeText(mContext, "pos --->" + position, Toast.LENGTH_SHORT).show(); 147 | mItemClickListener.onItemClick(position); 148 | } 149 | }); 150 | } 151 | 152 | @Override 153 | public int getItemCount() { 154 | return 4; 155 | } 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /app/src/main/java/com/cjj/buttomsheetdemo/BottomSheetDialogActivity.java: -------------------------------------------------------------------------------- 1 | package com.cjj.buttomsheetdemo; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.design.widget.BottomSheetDialog; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.LinearLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.ImageView; 14 | import android.widget.TextView; 15 | import android.widget.Toast; 16 | 17 | /** 18 | * Created by cjj on 2016/2/29. 19 | */ 20 | public class BottomSheetDialogActivity extends AppCompatActivity { 21 | private static final String shareStr[] = { 22 | "微信","QQ","空间","微博","GitHub","CJJ测试\nRecyclerView自适应","微信朋友圈","短信","推特","遇见" 23 | }; 24 | @Override 25 | protected void onCreate(@Nullable Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_dialog); 28 | findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() { 29 | @Override 30 | public void onClick(View v) { 31 | showBSDialog(); 32 | } 33 | }); 34 | } 35 | 36 | private void showBSDialog() { 37 | final BottomSheetDialog dialog = new BottomSheetDialog(this); 38 | View view = LayoutInflater.from(this).inflate(R.layout.dialog_layout, null); 39 | RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.bs_rv); 40 | recyclerView.setLayoutManager(new LinearLayoutManager(this)); 41 | SimpleStringRecyclerViewAdapter adapter = new SimpleStringRecyclerViewAdapter(this); 42 | adapter.setItemClickListener(new SimpleStringRecyclerViewAdapter.ItemClickListener() { 43 | @Override 44 | public void onItemClick(int pos) { 45 | dialog.dismiss(); 46 | Toast.makeText(BottomSheetDialogActivity.this, "pos--->" + pos, Toast.LENGTH_LONG).show(); 47 | } 48 | }); 49 | recyclerView.setAdapter(adapter); 50 | dialog.setContentView(view); 51 | dialog.show(); 52 | } 53 | 54 | public static class SimpleStringRecyclerViewAdapter 55 | extends RecyclerView.Adapter { 56 | 57 | public ItemClickListener mItemClickListener; 58 | 59 | public void setItemClickListener(ItemClickListener listener) { 60 | mItemClickListener = listener; 61 | } 62 | 63 | public interface ItemClickListener { 64 | public void onItemClick(int pos); 65 | } 66 | 67 | private Context mContext; 68 | 69 | public static class ViewHolder extends RecyclerView.ViewHolder { 70 | 71 | public final ImageView mImageView; 72 | public final TextView mTextView; 73 | 74 | public ViewHolder(View view) { 75 | super(view); 76 | mImageView = (ImageView) view.findViewById(R.id.avatar); 77 | mTextView = (TextView) view.findViewById(R.id.tv); 78 | } 79 | 80 | 81 | } 82 | 83 | public SimpleStringRecyclerViewAdapter(Context context) { 84 | super(); 85 | mContext = context; 86 | } 87 | 88 | @Override 89 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 90 | View view = LayoutInflater.from(parent.getContext()) 91 | .inflate(R.layout.list_item, parent, false); 92 | return new ViewHolder(view); 93 | } 94 | 95 | @Override 96 | public void onBindViewHolder(final ViewHolder holder, final int position) { 97 | 98 | holder.mTextView.setText(shareStr[position]); 99 | holder.mTextView.setOnClickListener(new View.OnClickListener() { 100 | @Override 101 | public void onClick(View v) { 102 | mItemClickListener.onItemClick(position); 103 | } 104 | }); 105 | } 106 | 107 | @Override 108 | public int getItemCount() { 109 | return shareStr.length; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /app/src/main/java/com/cjj/buttomsheetdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.cjj.buttomsheetdemo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.design.widget.FloatingActionButton; 6 | import android.support.design.widget.Snackbar; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.support.v7.widget.Toolbar; 9 | import android.view.View; 10 | import android.view.Menu; 11 | import android.view.MenuItem; 12 | 13 | public class MainActivity extends AppCompatActivity { 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_main); 19 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 20 | setSupportActionBar(toolbar); 21 | 22 | findViewById(R.id.sl).setOnClickListener(new View.OnClickListener() { 23 | @Override 24 | public void onClick(View v) { 25 | startActivity(new Intent(MainActivity.this, NestedScrollViewActivity.class)); 26 | } 27 | }); 28 | 29 | findViewById(R.id.rv).setOnClickListener(new View.OnClickListener() { 30 | @Override 31 | public void onClick(View v) { 32 | startActivity(new Intent(MainActivity.this, RecyclerViewActivity.class)); 33 | } 34 | }); 35 | 36 | findViewById(R.id.bs_dialog).setOnClickListener(new View.OnClickListener() { 37 | @Override 38 | public void onClick(View v) { 39 | startActivity(new Intent(MainActivity.this, BottomSheetDialogActivity.class)); 40 | } 41 | }); 42 | 43 | findViewById(R.id.beautiful).setOnClickListener(new View.OnClickListener() { 44 | @Override 45 | public void onClick(View v) { 46 | startActivity(new Intent(MainActivity.this, BeautifulBottomSheetActivity.class)); 47 | } 48 | }); 49 | 50 | 51 | } 52 | 53 | @Override 54 | public boolean onCreateOptionsMenu(Menu menu) { 55 | // Inflate the menu; this adds items to the action bar if it is present. 56 | getMenuInflater().inflate(R.menu.menu_main, menu); 57 | return true; 58 | } 59 | 60 | @Override 61 | public boolean onOptionsItemSelected(MenuItem item) { 62 | // Handle action bar item clicks here. The action bar will 63 | // automatically handle clicks on the Home/Up button, so long 64 | // as you specify a parent activity in AndroidManifest.xml. 65 | int id = item.getItemId(); 66 | 67 | //noinspection SimplifiableIfStatement 68 | if (id == R.id.action_settings) { 69 | return true; 70 | } 71 | 72 | return super.onOptionsItemSelected(item); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/com/cjj/buttomsheetdemo/NestedScrollViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.cjj.buttomsheetdemo; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.design.widget.BottomSheetBehavior; 6 | import android.support.design.widget.CoordinatorLayout; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.util.Log; 9 | import android.view.View; 10 | 11 | /** 12 | * Created by cjj on 2016/2/25. 13 | */ 14 | public class NestedScrollViewActivity extends AppCompatActivity { 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_ns); 20 | 21 | // The View with the BottomSheetBehavior 22 | CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.cl); 23 | View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet); 24 | final BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet); 25 | behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 26 | @Override 27 | public void onStateChanged(@NonNull View bottomSheet, int newState) { 28 | //这里是bottomSheet 状态的改变,根据slideOffset可以做一些动画 29 | Log.i("cjj", "newState--->" + newState); 30 | // ViewCompat.setScaleX(bottomSheet,1); 31 | // ViewCompat.setScaleY(bottomSheet,1); 32 | } 33 | 34 | @Override 35 | public void onSlide(@NonNull View bottomSheet, float slideOffset) { 36 | //这里是拖拽中的回调,根据slideOffset可以做一些动画 37 | Log.i("cjj", "slideOffset=====》" + slideOffset); 38 | // ViewCompat.setScaleX(bottomSheet,slideOffset); 39 | // ViewCompat.setScaleY(bottomSheet,slideOffset); 40 | } 41 | }); 42 | 43 | findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() { 44 | @Override 45 | public void onClick(View v) { 46 | if (behavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) { 47 | behavior.setState(BottomSheetBehavior.STATE_EXPANDED); 48 | } else { 49 | behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 50 | } 51 | } 52 | }); 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/cjj/buttomsheetdemo/RecyclerViewActivity.java: -------------------------------------------------------------------------------- 1 | package com.cjj.buttomsheetdemo; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | import android.support.design.widget.BottomSheetBehavior; 9 | import android.support.design.widget.CoordinatorLayout; 10 | import android.support.v4.view.ViewCompat; 11 | import android.support.v7.app.AppCompatActivity; 12 | import android.support.v7.widget.DefaultItemAnimator; 13 | import android.support.v7.widget.LinearLayoutManager; 14 | import android.support.v7.widget.RecyclerView; 15 | import android.util.Log; 16 | import android.view.LayoutInflater; 17 | import android.view.Menu; 18 | import android.view.View; 19 | import android.view.ViewGroup; 20 | import android.widget.ImageView; 21 | import android.widget.TextView; 22 | import android.widget.Toast; 23 | 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import java.util.Random; 27 | 28 | /** 29 | * Created by cjj on 2016/2/24. 30 | */ 31 | public class RecyclerViewActivity extends AppCompatActivity { 32 | 33 | public BottomSheetBehavior behavior; 34 | public RecyclerView recyclerView; 35 | public View blackView; 36 | 37 | @Override 38 | protected void onCreate(@Nullable Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | setContentView(R.layout.acitivity_rv); 41 | // The View with the BottomSheetBehavior 42 | CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.cl); 43 | recyclerView = (RecyclerView) findViewById(R.id.recyclerview); 44 | recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext())); 45 | SimpleStringRecyclerViewAdapter simpleStringRecyclerViewAdapter = new SimpleStringRecyclerViewAdapter(this); 46 | 47 | simpleStringRecyclerViewAdapter.setItemClickListener(new SimpleStringRecyclerViewAdapter.ItemClickListener() { 48 | @Override 49 | public void onItemClick(int pos) { 50 | behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 51 | Toast.makeText(RecyclerViewActivity.this, "pos--->" + pos, Toast.LENGTH_LONG).show(); 52 | } 53 | }); 54 | recyclerView.setAdapter(simpleStringRecyclerViewAdapter); 55 | recyclerView.setItemAnimator(new DefaultItemAnimator()); 56 | behavior = BottomSheetBehavior.from(recyclerView); 57 | behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 58 | @Override 59 | public void onStateChanged(@NonNull View bottomSheet, int newState) { 60 | if(newState == BottomSheetBehavior.STATE_COLLAPSED||newState == BottomSheetBehavior.STATE_HIDDEN){ 61 | // blackView.setBackgroundColor(Color.TRANSPARENT); 62 | blackView.setVisibility(View.GONE); 63 | } 64 | } 65 | 66 | @Override 67 | public void onSlide(@NonNull View bottomSheet, float slideOffset) { 68 | // React to dragging events 69 | blackView.setVisibility(View.VISIBLE); 70 | ViewCompat.setAlpha(blackView,slideOffset); 71 | } 72 | }); 73 | 74 | findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() { 75 | @Override 76 | public void onClick(View v) { 77 | behavior.setState(BottomSheetBehavior.STATE_EXPANDED); 78 | } 79 | }); 80 | 81 | blackView = findViewById(R.id.blackview); 82 | blackView.setBackgroundColor(Color.parseColor("#60000000")); 83 | blackView.setVisibility(View.GONE); 84 | blackView.setOnClickListener(new View.OnClickListener() { 85 | @Override 86 | public void onClick(View v) { 87 | behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 88 | } 89 | }); 90 | 91 | 92 | } 93 | 94 | 95 | @Override 96 | public boolean onCreateOptionsMenu(Menu menu) { 97 | getMenuInflater().inflate(R.menu.menu_main, menu); 98 | return true; 99 | } 100 | 101 | 102 | 103 | private List getRandomSublist(String[] array, int amount) { 104 | ArrayList list = new ArrayList<>(amount); 105 | Random random = new Random(); 106 | while (list.size() < amount) { 107 | list.add(array[random.nextInt(array.length)]); 108 | } 109 | return list; 110 | } 111 | 112 | public static class SimpleStringRecyclerViewAdapter 113 | extends RecyclerView.Adapter { 114 | 115 | public ItemClickListener mItemClickListener; 116 | 117 | public void setItemClickListener(ItemClickListener listener) { 118 | mItemClickListener = listener; 119 | } 120 | 121 | public interface ItemClickListener { 122 | public void onItemClick(int pos); 123 | } 124 | 125 | private Context mContext; 126 | 127 | public static class ViewHolder extends RecyclerView.ViewHolder { 128 | 129 | public final ImageView mImageView; 130 | public final TextView mTextView; 131 | 132 | public ViewHolder(View view) { 133 | super(view); 134 | mImageView = (ImageView) view.findViewById(R.id.avatar); 135 | mTextView = (TextView) view.findViewById(R.id.tv); 136 | } 137 | 138 | 139 | } 140 | 141 | public SimpleStringRecyclerViewAdapter(Context context) { 142 | super(); 143 | mContext = context; 144 | } 145 | 146 | @Override 147 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 148 | View view = LayoutInflater.from(parent.getContext()) 149 | .inflate(R.layout.list_item, parent, false); 150 | return new ViewHolder(view); 151 | } 152 | 153 | @Override 154 | public void onBindViewHolder(final ViewHolder holder, final int position) { 155 | // if (position == 0) { 156 | // holder.mImageView.setImageResource(R.drawable.a6); 157 | // } else if (position == 1) { 158 | // holder.mImageView.setImageResource(R.drawable.a5); 159 | // } 160 | // 161 | // holder.mImageView.setOnClickListener(new View.OnClickListener() { 162 | // @Override 163 | // public void onClick(View v) { 164 | //// Toast.makeText(mContext, "pos --->" + position, Toast.LENGTH_SHORT).show(); 165 | // mItemClickListener.onItemClick(position); 166 | // } 167 | // }); 168 | 169 | holder.mTextView.setOnClickListener(new View.OnClickListener() { 170 | @Override 171 | public void onClick(View v) { 172 | // Toast.makeText(mContext, "pos --->" + position, Toast.LENGTH_SHORT).show(); 173 | mItemClickListener.onItemClick(position); 174 | } 175 | }); 176 | } 177 | 178 | @Override 179 | public int getItemCount() { 180 | return 3; 181 | } 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/a5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-cjj/BottomSheets/b9527132881497052d1313cbab74ba2da561cb94/app/src/main/res/drawable/a5.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/a6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-cjj/BottomSheets/b9527132881497052d1313cbab74ba2da561cb94/app/src/main/res/drawable/a6.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/mingren1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-cjj/BottomSheets/b9527132881497052d1313cbab74ba2da561cb94/app/src/main/res/drawable/mingren1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/mingren2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-cjj/BottomSheets/b9527132881497052d1313cbab74ba2da561cb94/app/src/main/res/drawable/mingren2.jpg -------------------------------------------------------------------------------- /app/src/main/res/layout/acitivity_rv.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 25 | 26 | 27 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_beautiful.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 22 | 23 | 28 | 29 | 37 | 38 | 42 | 43 | 48 | 49 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_ns.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 15 | 23 | 24 | 28 | 29 | 37 | 38 | 44 | 45 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 |