Slider
滑块允许用户从一系列值中进行选择。
<com.google.android.material.slider.Slider
android:layout_width="wrap_content"
android:valueFrom="0.0"
android:valueTo="100.0"
android:stepSize="10.0"
android:id="@+id/slider"
android:layout_height="wrap_content"/>
Slider slider = findViewById(R.id.slider);
slider.addOnSliderTouchListener(new Slider.OnSliderTouchListener() {
@Override
public void onStartTrackingTouch(@NonNull Slider slider) {
Toast.makeText(BottomSheet.this,"onSilde"+slider.getValue(),Toast.LENGTH_SHORT).show();
}
@Override
public void onStopTrackingTouch(@NonNull Slider slider) {
Toast.makeText(BottomSheet.this,"onSilde"+slider,Toast.LENGTH_SHORT).show();
}
});
也可以使用范围Slider
xml:
<com.google.android.material.slider.RangeSlider
android:layout_width="match_parent"
android:valueFrom="0.0"
android:valueTo="100.0"
app:values="@array/initial_slider_values"
android:id="@+id/range"
android:layout_height="wrap_content"/>
array:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="initial_slider_values">
<item>20.0</item>
<item>70.0</item>
</array>
</resources>
监听方法相同
rangeSlider.addOnSliderTouchListener(new RangeSlider.OnSliderTouchListener() {
@Override
public void onStartTrackingTouch(@NonNull RangeSlider slider) {
}
@Override
public void onStopTrackingTouch(@NonNull RangeSlider slider) {
Toast.makeText(BottomSheet.this,"onSilde"+slider.getMinSeparation()+"___"+slider.getValues(),Toast.LENGTH_SHORT).show();
}
});
}
slider有一个属性
app:labelBehavior="floating"
floating表示会随着数值一起显示
gone是不显示
with bound是表示数值框也会随着占用一定的dp
设置数据格式
slider.setLabelFormatter(new LabelFormatter() {
@NonNull
@Override
public String getFormattedValue(float value) {
return value+"$";
}
});
设置滑动条颜色
app:trackColorActive="@color/colorBoderBlue"
app:trackColorInactive="@color/colorPrimary"
设置滑块
app:thumbColor="@color/colorPink"
app:thumbRadius = "10dp"
app:thumbColor="@color/colorPink"
app:thumbRadius = "10dp"
app:haloColor = "@color/colorLightGreen"
app:thumbStrokeColor = "@color/colorPurple"
app:thumbStrokeWidth = "10dp"
Snackbar
Snackbar在屏幕底部提供关于应用程序进程的简短信息。
Snackbar.make(v,"Snackbar",Snackbar.LENGTH_SHORT).setAction("Action",null).show();
默认情况下,Snackbar将锚定在其父视图的底部边缘。但是,您可以使用setAncorView方法使一个Snackbar出现在布局中的特定视图之上,例如FloatingActionButton。
setAnchorView(fab)
相关方法:
app:backgroundTint
setAnimationMode
getAnimationMode
TabLayout
xml:
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:id="@+id/tablayout"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@mipmap/onei"
android:text="label_1"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:icon="@mipmap/one"
android:layout_height="wrap_content"
android:text="label_2"
/>
Activity
TabLayout tabLayout = findViewById(R.id.tablayout);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//switch (tab.getPosition())
Log.d("_____-", "onTabSelected: "+tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
这样实现了基本的tab。但是一般tab都会在下面配合fragment使用,这时可以使用ViewPager。
ViewPager有两个版本
ViewPager
定义Adapter
public class MyViewPagerAdapter extends FragmentStatePagerAdapter {
Context context;
ArrayList<Fragment>fragments;
public MyViewPagerAdapter(@NonNull FragmentManager fm, int behavior, Context context, ArrayList<Fragment> fragments) {
super(fm, behavior);
this.context = context;
this.fragments = fragments;
}
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return "title"+position;
}
@Override
public int getCount() {
return fragments.size();
}
}
为Tab绑定这个Adapter的逻辑
ViewPager viewPager = findViewById(R.id.viewpager);
ArrayList<Fragment> list = new ArrayList<>();
list.add(PagerFragment.newInstance("PagerFragment1"));
list.add(PagerFragment.newInstance("PagerFragment2"));
viewPager.setAdapter(new MyViewPager(getSupportFragmentManager(),0,this,list));
tabLayout.setupWithViewPager(viewPager);
TabLayout.Tab a = tabLayout.getTabAt(0);
a.setIcon(getResources().getDrawable(R.mipmap.one));
xml中只需要把ViewPager放在tab下面就可以了。
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:id="@+id/viewpager"
android:layout_height="match_parent"/>
参数0可以点进去看源码。setIcon可以设置icon
ViewPager2
final ArrayList<Fragment> list = new ArrayList<>();
list.add(PagerFragment.newInstance("PagerFragment1"));
list.add(PagerFragment.newInstance("PagerFragment2"));
ViewPager2 viewPager2 = findViewById(R.id.viewpager);
viewPager2.setAdapter(new FragmentStateAdapter(getSupportFragmentManager(), getLifecycle()) {
@Override
public int getItemCount() {
return list.size();
}
@NonNull
@Override
//FragmentStateAdapter内部自己会管理已实例化的fragment对象。
public Fragment createFragment(int position) {
return list.get(position);
}
});
TabLayoutMediator tabLayoutMediator = new TabLayoutMediator(tabLayout,viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
tab.setText("caonima"+position);
BadgeDrawable badgeDrawable = tab.getOrCreateBadge();
badgeDrawable.setNumber(position);//设置数字
}
});
viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {//监听页面变化
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
Log.d("_____", "onPageSelected: "+position);
}
});
tabLayoutMediator.attach();//调用这个attach才会绑定
xml中把ViewPager2放在Tab下面即可
两种都可以使用,但是官方推荐ViewPager2,前者已经不维护了。而且个人在使用方面2的功能会更多
Tablayout注意
默认情况下Tab会被所有选项占据一个match parent
不过使用app:tabMode="scrollable"允许tab内容进行滚动
相关方法:
android:background背景颜色
tabIconTint icon颜色
tabIndicatorColor 选中时下框的颜色
tabGravity 内容分布
TextInputLayout
方法相似 多加了一个starticon和endicon
endIconmode这里 custom是自己定制,还有一个是password_toggle。用来隐藏密码,此时edittext类型应该是password
还有clear_text,点击可以清除文本内容
以下属性均要放在layout里而不是edittext里
app:startIconDrawable ="@mipmap/three"
app:counterEnabled="true"计数器
app:counterMaxLength="5"计数最大值
app:prefixText="prefix"前缀
app:suffixText="suffix"后缀
app:helperTextEnabled="true"帮助文本
app:helperText="tring/helper_text"帮助文本内容
app:errorEnabled="true"错误提醒
app:endIconMode="clear_text"右侧icon类型
app:boxBackgroundColor="@color/colorLittlePink"文本框背景
内容太多了 自己上官网看吧
TimePicker
先看效果
Fragment定义:
import android.app.TimePickerDialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.SwitchCompat;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.google.android.material.button.MaterialButtonToggleGroup;
import com.google.android.material.timepicker.MaterialTimePicker;
import com.google.android.material.timepicker.TimeFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
/** A fragment that displays the main Picker demos for the Catalog app. */
public class TimePickerMainDemoFragment extends Fragment {
public static TimePickerMainDemoFragment newInstance() {
Bundle args = new Bundle();
TimePickerMainDemoFragment fragment = new TimePickerMainDemoFragment();
fragment.setArguments(args);
return fragment;
}
private int hour;
private int minute;
private final SimpleDateFormat formatter = new SimpleDateFormat("hh:mm a", Locale.getDefault());
@TimeFormat
private int clockFormat;
private TextView textView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ViewGroup view = (ViewGroup) inflater.inflate(R.layout.time_picker_main_demo, container, false);
Button button = view.findViewById(R.id.timepicker_button);
textView = view.findViewById(R.id.timepicker_time);
MaterialButtonToggleGroup timeFormatToggle = view.findViewById(R.id.time_format_toggle);
clockFormat = TimeFormat.CLOCK_12H;
timeFormatToggle.check(R.id.time_format_12h);
timeFormatToggle.addOnButtonCheckedListener(//监听时区变化
new MaterialButtonToggleGroup.OnButtonCheckedListener() {
@Override
public void onButtonChecked(MaterialButtonToggleGroup group, int checkedId, boolean isChecked) {
boolean isSystem24Hour = DateFormat.is24HourFormat(TimePickerMainDemoFragment.this.getContext());
boolean is24Hour = checkedId == R.id.time_format_24h || (checkedId == R.id.time_format_system && isSystem24Hour);
clockFormat = is24Hour ? TimeFormat.CLOCK_24H : TimeFormat.CLOCK_12H;
}
});
final SwitchCompat frameworkSwitch = view.findViewById(R.id.framework_switch);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (frameworkSwitch.isChecked()) {
TimePickerMainDemoFragment.this.showFrameworkTimepicker();
return;
}
//MaterialTimePicker继承fragmentdialog 这个是系统的控件?
final MaterialTimePicker materialTimePicker = new MaterialTimePicker.Builder()//利用builders来构建时间选择器
.setTimeFormat(clockFormat)
.setHour(hour)//设置默认时间
.setMinute(minute)
.build();
materialTimePicker.show(TimePickerMainDemoFragment.this.requireFragmentManager(), "fragment_tag");
materialTimePicker.addOnPositiveButtonClickListener(new View.OnClickListener() {
@Override
public void onClick(View dialog) {
int newHour = materialTimePicker.getHour();
int newMinute = materialTimePicker.getMinute();
TimePickerMainDemoFragment.this.onTimeSet(newHour, newMinute);//展示并更新时间
}
});
}
});
return view;
}
//区别前一个 这个继承 AlertDialog(感觉没啥区别)
private void showFrameworkTimepicker() {
android.app.TimePickerDialog timePickerDialog = new android.app.TimePickerDialog(getContext(),
new TimePickerDialog.OnTimeSetListener() {//应该是内部已经封装好了方法 点击了确定就会调用此方法
@Override
public void onTimeSet(android.widget.TimePicker view, int hourOfDay, int minute) {
TimePickerMainDemoFragment.this.onTimeSet(hourOfDay, minute);//完成,跟新ui 设置时间
}
}, hour, minute, clockFormat == TimeFormat.CLOCK_24H);
timePickerDialog.show();
}
private void onTimeSet(int newHour, int newMinute) {//把获得的时间数据存放到日历中,用日历格式显示出来
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, newHour);
cal.set(Calendar.MINUTE, newMinute);
cal.setLenient(false);
String format = formatter.format(cal.getTime());
textView.setText(format);
hour = newHour;
minute = newMinute;
}
}
layout:
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/timepicker_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:text="@string/select_time"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/framework_switch" />
<TextView
android:id="@+id/timepicker_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginRight="24dp"
android:text="@string/default_time"
app:layout_constraintBottom_toBottomOf="@id/timepicker_button"
app:layout_constraintStart_toEndOf="@id/timepicker_button"
app:layout_constraintTop_toTopOf="@id/timepicker_button" />
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/time_format_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:selectionRequired="true"
app:singleSelection="true">
<Button
android:id="@+id/time_format_12h"
style="?attr/materialButtonOutlinedStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/time_format_12" />
<Button
android:id="@+id/time_format_24h"
style="?attr/materialButtonOutlinedStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/time_format_24" />
<Button
android:id="@+id/time_format_system"
style="?attr/materialButtonOutlinedStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/time_format_system" />
</com.google.android.material.button.MaterialButtonToggleGroup>
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/framework_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="@string/use_framework_dialog"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/time_format_toggle" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
个人感觉调用系统的比较丑