轮播图
依赖
implementation 'io.github.youth5201314:banner:2.2.2'
implementation 'com.github.bumptech.glide:glide:4.14.2'
添加权限
<uses-permission android:name="android.permission.INTERNET" />
layout参照"item_banner"
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">
<com.youth.banner.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="250dp"/>
</LinearLayout>
其他布局中引入:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/item_banner"/>
</LinearLayout>
activity中:
Banner banner = findViewById(R.id.banner);
//模拟图片集合
List<String> stringList = new ArrayList<>();
//stringList.add("图片链接");
stringList.add("https://img.zcool.cn/community/01af785bb96e64a8012099c842e316.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
stringList.add("https://img.zcool.cn/community/01446c5bb96e2da8012099c883c002.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
stringList.add("https://img.zcool.cn/community/0194525bb96e51a8012099c8fb70c5.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
stringList.add("https://img.zcool.cn/community/0118935bb96e22a801213dea403d56.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
stringList.add("https://img.zcool.cn/community/015a4d5bb96e5fa801213deacbb786.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
stringList.add("https://img.zcool.cn/community/0128535bb96e85a8012099c86c34f9.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
stringList.add("https://img.zcool.cn/community/014c645bb96e92a801213dea6e7782.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
stringList.add("https://img.zcool.cn/community/01516e5bb96e9fa8012099c88933ea.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
stringList.add("https://img.zcool.cn/community/0108395bb96ea1a801213dea462e1a.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_1280,limit_1/sharpen,100/format,webp/quality,q_100");
//轮播图
banner.setAdapter(new BannerImageAdapter<String>(stringList)
{
@Override
public void onBindView(BannerImageHolder holder, String data, int position, int size)
{
Glide.with(holder.itemView).load(data).apply(RequestOptions.bitmapTransform(new RoundedCorners(30))).into(holder.imageView);
}
});
//设置指示器颜色和形状
banner.setIndicator(new CircleIndicator(this));
banner.setIndicatorNormalColor(R.color.gray0);
banner.setIndicatorSelectedColor(R.color.blue);
//添加画廊效果
banner.setBannerGalleryEffect(50, 10);
设置图片圆角:
注意:如果添加了画廊效果,圆角效果会消失。 法一:在banner_item中添加:
app:banner_round_top_left="true"
app:banner_round_top_right="true"
app:banner_round_bottom_left="true"
app:banner_round_bottom_right="true"
app:banner_radius="50dp"
法二:在activity中添加:
banner.setBannerRound(100);
更多功能
从相册选择照片
依赖
implementation 'com.github.lovetuzitong:MultiImageSelector:1.2'
权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
申请权限
boolean AskPermission()
{
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
Toast.makeText(context, "当前存储卡不可用", Toast.LENGTH_SHORT).show();
return false;
}
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(activity, new String[]{
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_EXTERNAL_STORAGE_CODE);
return false;
}
return true;
}
activity中
- 开始选择照片
Intent intent = new Intent(context, MultiImageSelectorActivity.class);
// 是否显示调用相机拍照
intent.putExtra(MultiImageSelectorActivity.EXTRA_SHOW_CAMERA, true);
intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_COUNT, 最大图片选择数量);
intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_MODE, MultiImageSelectorActivity.MODE_MULTI);
startActivityForResult(intent, mode);
- 拍照
在清单文件中添加路径
<!--File uri 路径-->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.mobilelearning.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
- activity中
void TakePhoto(int mode)
{
File outputImage = new File(context.getExternalCacheDir(), getHeadImgName());
try
{
if (outputImage.exists())
{
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e)
{
e.printStackTrace();
}
// 判断安卓的版本是否高于7.0,高于则调用高于的方法,低于则调用低于的方法
if (Build.VERSION.SDK_INT >= 24)
{
imageUri = FileProvider.getUriForFile(activity,
"com.example.mobilelearning.fileprovider", outputImage);
}
else
{
imageUri = Uri.fromFile(outputImage);
}
// 启动相机程序
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, mode);
}
- 结束后返回结果
//如果是fragment,在主activity中也需要重写该方法
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
// activity.RESULT_OK!!!需要在父活动中将RESULT_OK设置为true!!!
if (resultCode != Activity.RESULT_OK)
return;
switch (requestCode)
{
case CHOOSE_PHOTO:
ArrayList<String> path = data.getStringArrayListExtra(MultiImageSelectorActivity.EXTRA_RESULT);
//do something, 照片路径储存在path
break;
default:
break;
}
}
主activity中的重写
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
View Banner = findViewById(R.id.banner);
Banner.setVisibility(View.GONE);
setResult(RESULT_OK);
super.onActivityResult(requestCode, resultCode, data);
}
简单对话框
导入依赖
implementation 'com.github.Shashank02051997:FancyAlertDialog-Android:0.3'
activity中
FancyAlertDialog.Builder
.with(this)
.setTitle("Rate us if you like the app")
.setBackgroundColor(Color.parseColor("#303F9F"))
.setMessage("Do you really want to Exit ?")
.setNegativeBtnText("Cancel")
.setPositiveBtnBackground(Color.parseColor("#FF4081"))
.setPositiveBtnText("Rate")
.setNegativeBtnBackground(Color.parseColor("#FFA9A7A8"))
.setIcon(R.drawable.hand, View.VISIBLE)
.setAnimation(Animation.POP)
.isCancellable(true)
.onPositiveClicked(dialog -> Toast.makeText(this, "Rate", Toast.LENGTH_SHORT).show())
.onNegativeClicked(dialog -> Toast.makeText(this, "Cancel", Toast.LENGTH_SHORT).show())
.build()
.show();
推荐颜色和图案搭配
蓝-#30409F-R.drawable.exclamatory
绿-#378E3C-R.drawable.yes
橙-#F57C00-R.drawable.hand
红-#D23030-R.drawable.no
单选对话框
activity中
public void singleDialog(String[] options, String title)
{
new AlertDialog.Builder(this)
.setTitle(title)
.setIcon(R.mipmap.ic_launcher)
.setSingleChoiceItems(options, -1, (dialog, which) ->
{
//which是选项的下标,从0开始
Toast.makeText(this, "选中了第" + which + "个", Toast.LENGTH_SHORT).show();
})
.setPositiveButton("确定", (dialog, which) -> Toast.makeText(this, "确定", Toast.LENGTH_SHORT).show())
.show();
}
多选对话框
public void multiDialog(String[] options, String title)
{
boolean[] flags = new boolean[options.length];
new AlertDialog.Builder(this).setTitle(title)
.setIcon(R.mipmap.ic_launcher)
//第一个参数多选的选择数组,第二个多选的选择状态数组,如果null,则默认全部没选,第三个是选中选择的事件
.setMultiChoiceItems(options, null, (dialog, which, isChecked) -> flags[which] = isChecked)
.setPositiveButton("确定", (dialog, which) ->
{
//flags代表所有选项的状态
//do something ...
//将所有选项的状态改为未选中状态
Arrays.fill(flags, false);
}).show();
}
自定义传值对话框
编写layout(i.e. item_dialog.xml)
编写activity(i.e. item_dialog.java)
public class item_dialog extends Dialog implements View.OnClickListener
{
1. 声明变量,就是自定义对话框有几个控件,比如:
private EditText edit1, edit2;
private Button yes, no;
Activity activity;
2. 要从主activity传给对话框的值--从构造函数传入对话框类,比如:
public item_dialog(Activity activity,String edit_default)
{
edit1.setText(edit_default);
this.
}
3. 将laytou中的对话框与定义的变量关联起来
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.item_layout);
setCanceledOnTouchOutside(false);
//初始化控件
//这里省略以下过程:通过findViewById的方法对变量进行定义
yes.setOnClickListener(this);
no.setOnClickListener(this);
//这里是为了调整宽度,不知道为啥对话框弹出式宽度变得很窄,所以需要以下代码
Window dialogWindow = this.getWindow();
WindowManager m = activity.getWindowManager();
Display d = m.getDefaultDisplay(); // 获取屏幕宽、高度
WindowManager.LayoutParams p = dialogWindow.getAttributes(); // 获取对话框当前的参数值
p.width = (int) (d.getWidth() * 0.95); // 宽度设置为屏幕的0.65,根据实际情况调整
dialogWindow.setAttributes(p);
}
4. 如果需要传值,比如按下yes的时候,把编辑框中的文本传给主activity,则设立一个监听器接口
public interface TestListener
{
//将要传回的值写在括号中,第一个参数要写dialog
void yesListenter(Dialog dialog, EditText title, EditText content);
}
在变量处添加:
private TestListener testListener;
在构造函数处添加一个参数 TestListener testListener,且this.testListener = testListener;
在yes按钮的监听器中进行传值:
testListener.yesListener(this, edit1.getText().toString(), edit2.getText().toString());
当然,可以选择传文本,也可以选择直接把控件(edit1,edit2)传到主activity,如果还需要对控件做些什么的话。
}
编写主activity
直接new一个item_dialog类,然后在里面重写接口。
!记得最后要.show();