一、线程中使用Handler执行轮询任务
1、添加任务
LinkedList<Runnable> mTaskQueue = new LinkedList<>();
private synchronized void addTask(Runnable runnable) {
mTaskQueue.add(runnable);
try {
if(mPoolThreadHandler == null) {
// 请求为0阻塞,无法获取信号量则阻塞
mSemaphoreThreadHandler.acquire();
}
} catch (InterruptedException e) {
}
mPoolThreadHandler.sendEmptyMessage(0);
}
由于初始化init方法有可能没有执行完就执行添加任务的方法,那么Handler为null无法执行,这里使用信号量来管理。
2、轮询任务
// 后台轮询线程
mPoolThread = new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
mPoolThreadHandler = new Handler(){
// 线程池中取任务执行
@Override
public void handleMessage(Message msg) {
mThreadPool.execute(getTask());
try {
// 当信号量为3,那么第4个时就会阻塞
mSemaphoreThreadPool.acquire();
} catch (InterruptedException e) {
}
}
};
// 轮询Handler已经初始化完毕,释放信号量
mSemaphoreThreadHandler.release();
Looper.loop();// 轮询
}
});
mPoolThread.start();
3、执行任务
固定线程数量的线程池中执行,使用信号量管理任务,一个task执行完释放一个信号量,轮询线程中获取信号量,如果取不到就会阻塞
ExecutorService mThreadPool = Executors.newFixedThreadPool(threadCount);
Semaphore mSemaphoreThreadPool = new Semaphore(threadCount);
// Task
new Runnable(){
@Override
public void run() {
// 加载图片
// 获取图片大小
ImageSize imageSize = getImageViewSize(imageView);
// 压缩图片
Bitmap bm = decodeSampledBitmapFromPath(path, imageSize.width, imageSize.height);
// 图片加载到缓存
addBitmapToLruCache(path, bm);
Message message = Message.obtain();
ImageHolder holder = new ImageHolder();
holder.bitmap = bm;
holder.path = path;
holder.imageView = imageView;
message.obj = holder;
mUIHandler.sendMessage(message);
// 释放一个信号量
mSemaphoreThreadPool.release();
}
}
二、定义PopWindow
1、设置宽高、焦点、背景
2、显示位置,如果下方位置不够显示,则会显示在上方
popwindow.showAsDropDown(button, 0, 0);
三、源码
public class MainActivity extends AppCompatActivity {
private int mMaxCount;
private List<String> mImgs;
private File mCurrentDir;
private List<FolderBean> list = new ArrayList<>();
private ProgressDialog pd;
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
pd.dismiss();
data2View();
return true;
}
});
private GridView gridView;
private TextView text1;
private TextView text2;
private RelativeLayout relativeLayout;
private ListPopwindow popwindow;
private ImageAdapter mAdapter;
private Button button;
private void data2View() {
if(mCurrentDir == null){
Toast.makeText(this, "未扫描到图片", Toast.LENGTH_LONG).show();
return;
}
mImgs = Arrays.asList(mCurrentDir.list());
mAdapter = new ImageAdapter(this, mImgs, mCurrentDir.getAbsolutePath());
gridView.setAdapter(mAdapter);
text1.setText("数量:"+mMaxCount);
text2.setText(mCurrentDir.getName());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
relativeLayout = (RelativeLayout) findViewById(R.id.relative_layout);
button = (Button) findViewById(R.id.button);
text1 = (TextView) findViewById(R.id.text_1);
text2 = (TextView) findViewById(R.id.text_2);
gridView = (GridView) findViewById(R.id.grid_view);
initData();
initPopWindow();
relativeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popwindow.setAnimationStyle(R.style.dir);
popwindow.showAsDropDown(button, 0, 0);
// 内容区域变暗
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 0.3f;
getWindow().setAttributes(lp);
}
});
Handler h = new Handler();
h.postDelayed(new Runnable() {
@Override
public void run() {
iniPopupWindow();
}
}, 10000);
}
private void initPopWindow() {
popwindow = new ListPopwindow(this, list);
popwindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
// 内容区域变亮
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1.0f;
getWindow().setAttributes(lp);
}
});
popwindow.setListemer(new ListPopwindow.OnDirSelectedListener() {
@Override
public void onSelected(FolderBean bean) {
mCurrentDir = new File(bean.getDir());
mImgs = Arrays.asList(mCurrentDir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
if(filename.endsWith(".jpg")||filename.endsWith(".jpeg")||filename.endsWith(".png")){
return true;
}
return false;
}
}));
mAdapter = new ImageAdapter(MainActivity.this, mImgs, mCurrentDir.getAbsolutePath());
gridView.setAdapter(mAdapter);
text2.setText(mImgs.size()+"");
text1.setText(bean.getName());
popwindow.dismiss();
}
});
}
/**
* 利用contentprovide扫描图片
*/
private void initData() {
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Toast.makeText(this, "没有SD卡", Toast.LENGTH_LONG).show();
return;
}
pd = ProgressDialog.show(this, null, "loading...");
new Thread(){
@Override
public void run() {
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
ContentResolver cr = MainActivity.this.getContentResolver();
Cursor cursor = cr.query(uri, null, MediaStore.Images.Media.MIME_TYPE+"= ? or "+MediaStore.Images.Media.MIME_TYPE+"= ?",
new String[]{"image/jpeg", "image/png"}, MediaStore.Images.Media.DATE_MODIFIED);
Set<String> mDirPaths = new HashSet<String>();
while(cursor.moveToNext()){
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
File parentFile = new File(path).getParentFile();
if(parentFile == null){
continue;
}
// 获取当前文件夹
String dirPath = parentFile.getAbsolutePath();
FolderBean fb = null;
if(mDirPaths.contains(dirPath)){
continue;
}
mDirPaths.add(dirPath);
fb = new FolderBean();
fb.setDir(dirPath);// 目录
fb.setFirstImgPath(path);// 第一个图片地址
// 防止为null
if(parentFile.list() == null){
continue;
}
int picSize = parentFile.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
if(filename.endsWith(".jpg")||filename.endsWith(".jpeg")||filename.endsWith(".png")){
return true;
}
return false;
}
}).length;
fb.setCount(picSize);
list.add(fb);
if(picSize > mMaxCount){
mMaxCount = picSize;
mCurrentDir = parentFile;
}
}
// 释放
cursor.close();
mHandler.sendEmptyMessage(0);
}
}.start();
}
private void iniPopupWindow() {
LayoutInflater inflater = (LayoutInflater) MainActivity.this
.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.popup_item, null);
PopupWindow pwMyPopWindow = new PopupWindow(layout);
pwMyPopWindow.setFocusable(true);// 加上这个popupwindow中的ListView才可以接收点击事件
// 控制popupwindow的宽度和高度自适应
pwMyPopWindow.setWidth(100);
pwMyPopWindow.setHeight(200);
// 控制popupwindow点击屏幕其他地方消失
pwMyPopWindow.setBackgroundDrawable(MainActivity.this.getResources().getDrawable(
R.drawable.bg_popupwindow));// 设置背景图片,不能在布局中设置,要通过代码来设置
pwMyPopWindow.setOutsideTouchable(true);// 触摸popupwindow外部,popupwindow消失。这个要求你的popupwindow要有背景图片才可以成功,如上
pwMyPopWindow.showAsDropDown(button);// 显示
}
}
public class ListPopwindow extends PopupWindow{
private int mWidth;
private int mHeight;
private View mContentView;
private ListView mListView;
private List<FolderBean> mDatas;
public interface OnDirSelectedListener{
void onSelected(FolderBean bean);
}
public OnDirSelectedListener listemer;
public void setListemer(OnDirSelectedListener listemer) {
this.listemer = listemer;
}
public ListPopwindow(Context context, List<FolderBean> list){
calWidthAndHeight(context);
mContentView = LayoutInflater.from(context).inflate(R.layout.popup, null);
mDatas = list;
setContentView(mContentView);
setWidth(mWidth);
setHeight(mHeight);
setFocusable(true);
setTouchable(true);
// 点击外部消失
setOutsideTouchable(true);
setBackgroundDrawable(new BitmapDrawable());
setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// 点击外部
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
dismiss();
return true;
}
return false;
}
});
initView(context);
initEvent();
}
private void initEvent() {
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(listemer != null){
listemer.onSelected(mDatas.get(position));
}
}
});
}
private void initView(Context context) {
mListView = (ListView) mContentView.findViewById(R.id.list_view);
mListView.setAdapter(new ListDirAdapter(context, mDatas));
}
/**
* 计算pop宽高
* @param context
*/
private void calWidthAndHeight(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics d = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(d);
mWidth = d.widthPixels;
mHeight = (int) (d.heightPixels*0.7);
}
private class ListDirAdapter extends ArrayAdapter<FolderBean>{
private LayoutInflater mInflater;
private List<FolderBean> mDatas;
public ListDirAdapter(Context context, List<FolderBean> objects) {
super(context, 0, objects);
mInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.popup_item, parent, false);
holder.mImg = (ImageView) convertView.findViewById(R.id.imageView);
holder.mDirName = (TextView) convertView.findViewById(R.id.textView);
holder.mDirCount = (TextView) convertView.findViewById(R.id.textView2);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
FolderBean bean = getItem(position);
holder.mImg.setImageResource(R.mipmap.pictures_no);
ImageLoader.getmInstance(3, ImageLoader.Type.LIFO).loadImage(
bean.getFirstImgPath(), holder.mImg);
holder.mDirName.setText(bean.getName());
holder.mDirCount.setText(bean.getCount()+"");
return convertView;
}
private class ViewHolder{
ImageView mImg;
TextView mDirName;
TextView mDirCount;
}
}
}
public class ImageLoader {
private static ImageLoader mInstance;
private ImageLoader(){}
// 图片缓存
private LruCache<String, Bitmap> mLruCache;
private ExecutorService mThreadPool;
// 线程池数量
private static final int default_thread_count = 1;
// 队列调度方式
private Type mType = Type.LIFO;
// 任务队列
private LinkedList<Runnable> mTaskQueue;
// 轮询线程
private Thread mPoolThread;
private Handler mPoolThreadHandler;
private Handler mUIHandler;
// 信号量 用于等待同步
private Semaphore mSemaphoreThreadHandler = new Semaphore(0);
private Semaphore mSemaphoreThreadPool;
public enum Type{
FIFO,LIFO;
}
public static ImageLoader getmInstance(int threadCount, Type type){
if(mInstance == null){// 过滤掉大部分处理,提高性能
synchronized (ImageLoader.class){
if(mInstance == null){
mInstance = new ImageLoader(threadCount, type);
}
}
}
return mInstance;
}
private ImageLoader(int threadCount, Type type){
init(threadCount, type);
}
/**
* 初始化
* @param threadCount
* @param type
*/
private void init(int threadCount, Type type) {
// 后台轮询线程
mPoolThread = new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
mPoolThreadHandler = new Handler(){
// 线程池中取任务执行
@Override
public void handleMessage(Message msg) {
mThreadPool.execute(getTask());
try {
// 当信号量为3,那么第4个时就会阻塞
mSemaphoreThreadPool.acquire();
} catch (InterruptedException e) {
}
}
};
// 释放信号量
mSemaphoreThreadHandler.release();
Looper.loop();// 轮询
}
});
mPoolThread.start();
// 获取应用最大内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheMemory = maxMemory/8;
mLruCache = new LruCache<String, Bitmap>(cacheMemory){
// 测量每个图片的大小
@Override
protected int sizeOf(String key, Bitmap value) {
// 每行字节数*高度
return value.getRowBytes()*value.getHeight();
}
};
// 线程池
mThreadPool = Executors.newFixedThreadPool(threadCount);
mTaskQueue = new LinkedList<>();
mType = type;
mSemaphoreThreadPool = new Semaphore(threadCount);
}
/**
* 设置图片
* @param path
* @param imageView
*/
public void loadImage(final String path,final ImageView imageView){
imageView.setTag(path);
if(mUIHandler == null){
mUIHandler = new Handler(new Handler.Callback(){
@Override
public boolean handleMessage(Message msg) {
// 获取得到的图片
ImageHolder holder = (ImageHolder) msg.obj;
Bitmap bitmap = holder.bitmap;
ImageView iv = holder.imageView;
String path = holder.path;
if(iv.getTag().toString().equals(path)){
iv.setImageBitmap(bitmap);
}
return true;
}
});
}
Bitmap bmp = getBitmapFromLruCache(path);
if(bmp != null){
Message message = Message.obtain();
ImageHolder holder = new ImageHolder();
holder.bitmap = bmp;
holder.path = path;
holder.imageView = imageView;
message.obj = holder;
mUIHandler.sendMessage(message);
}else{
addTask(new Runnable(){
@Override
public void run() {
// 加载图片
// 获取图片大小
ImageSize imageSize = getImageViewSize(imageView);
// 压缩图片
Bitmap bm = decodeSampledBitmapFromPath(path, imageSize.width, imageSize.height);
// 图片加载到缓存
addBitmapToLruCache(path, bm);
Message message = Message.obtain();
ImageHolder holder = new ImageHolder();
holder.bitmap = bm;
holder.path = path;
holder.imageView = imageView;
message.obj = holder;
mUIHandler.sendMessage(message);
// 释放一个信号量
mSemaphoreThreadPool.release();
}
});
}
}
/**
* 图片加入缓存
* @param path
* @param bm
*/
private void addBitmapToLruCache(String path, Bitmap bm) {
if(getBitmapFromLruCache(path) != null){
if(bm != null){
mLruCache.put(path, bm);
}
}
}
/**
* 压缩图片
* @param path
* @param width
* @param height
* @return
*/
private Bitmap decodeSampledBitmapFromPath(String path, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
// 获取图片宽高,不加载到内存中
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
options.inSampleSize = caculateInSampleSize(options, width, height);
options.inJustDecodeBounds = false;
Bitmap bm = BitmapFactory.decodeFile(path, options);
return bm;
}
private int caculateInSampleSize(BitmapFactory.Options options, int width, int height) {
int w = options.outWidth;
int h = options.outHeight;
int inSampleSize = 1;
if(w > width || h > height){
int widthRadio = Math.round(w*1.0f/width);
int heightRadio = Math.round(h*1.0f/height);
inSampleSize = Math.max(widthRadio, heightRadio);
}
return inSampleSize;
}
/**
* 根据ImageView获取宽高
* @param imageView
* @return
*/
private ImageSize getImageViewSize(ImageView imageView) {
DisplayMetrics displayMetrics = imageView.getContext().getResources().getDisplayMetrics();
ImageSize imageSize = new ImageSize();
ViewGroup.LayoutParams lp = imageView.getLayoutParams();
int width = imageView.getWidth();// imageView实际宽度,未布局时没有值
if(width <= 0){
width = lp.width;// layout中声明的宽度
}
if(width <= 0){
// API 16
// width = imageView.getMaxWidth();// 检查最大值
width = getImageViewFieldValue(imageView, "mMaxWidth");
}
if(width <=0 ){
width = displayMetrics.widthPixels;// 屏幕宽度
}
int height = imageView.getHeight();// imageView实际宽度,未布局时没有值
if(height <= 0){
height = lp.height;// layout中声明的宽度
}
if(height <= 0){
// height = imageView.getMaxHeight();// 检查最大值
}
if(height <=0 ){
height = displayMetrics.heightPixels;// 屏幕宽度
}
imageSize.width = width;
imageSize.height = height;
return imageSize;
}
/**
* 反射取属性
* @param object
* @param fieldName
* @return
*/
private static int getImageViewFieldValue(Object object, String fieldName){
int value = 0;
try {
Field field = ImageView.class.getDeclaredField(fieldName);
field.setAccessible(true);
int fieldValue = field.getInt(object);
if(fieldValue > 0 && fieldValue < Integer.MAX_VALUE){
value = fieldValue;
}
} catch (Exception e) {
}
return value;
}
/**
* 添加任务
* @param runnable
*/
private synchronized void addTask(Runnable runnable) {
mTaskQueue.add(runnable);
try {
if(mPoolThreadHandler == null) {
// 请求为0阻塞
mSemaphoreThreadHandler.acquire();
}
} catch (InterruptedException e) {
}
mPoolThreadHandler.sendEmptyMessage(0);
}
public Runnable getTask() {
if(mType == Type.FIFO){
return mTaskQueue.removeFirst();
}else if(mType == Type.LIFO){
return mTaskQueue.removeLast();
}
return null;
}
private Bitmap getBitmapFromLruCache(String path) {
return mLruCache.get(path);
}
private class ImageHolder{
Bitmap bitmap;
ImageView imageView;
String path;
}
private class ImageSize{
int width;
int height;
}
}
public class ImageAdapter extends BaseAdapter {
static Set<String> mSelectedImg = new HashSet<>();
private String mDirPath;
private List<String> mImgPaths;
private LayoutInflater mInflater;
public ImageAdapter(Context context, List<String> mDatas, String dirPath){
this.mDirPath = dirPath;
this.mImgPaths = mDatas;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mImgPaths.size();
}
@Override
public Object getItem(int position) {
return mImgPaths.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null){
convertView = mInflater.inflate(R.layout.layout, parent, false);
holder = new ViewHolder();
holder.mImg = (ImageView) convertView.findViewById(R.id.id_item_image);
holder.mSelect = (ImageButton) convertView.findViewById(R.id.id_item_select);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
// 初始化
holder.mImg.setImageResource(R.mipmap.pictures_no);
holder.mSelect.setImageResource(R.mipmap.picture_unselected);
holder.mImg.setColorFilter(null);
ImageLoader.getmInstance(3, ImageLoader.Type.LIFO)
.loadImage(mDirPath+"/"+mImgPaths.get(position), holder.mImg);
final String filePath = mDirPath+"/"+mImgPaths.get(position);
holder.mImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 已选择
if(mSelectedImg.contains(filePath)){
mSelectedImg.remove(filePath);
holder.mImg.setColorFilter(null);
holder.mSelect.setImageResource(R.mipmap.picture_unselected);
}else{
mSelectedImg.add(filePath);
holder.mImg.setColorFilter(Color.parseColor("#77000000"));
holder.mSelect.setImageResource(R.mipmap.pictures_selected);
}
//notifyDataSetChanged();
}
});
/*if(mSelectedImg.contains(filePath)){
holder.mImg.setColorFilter(Color.parseColor("#77000000"));
holder.mSelect.setImageResource(R.mipmap.pictures_selected);
}*/
return convertView;
}
private class ViewHolder{
ImageView mImg;
ImageButton mSelect;
}
}
public class FolderBean {
// 文件夹路径
public String dir;
public String firstImgPath;
public String name;
public int count;
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
int lastIndexOf = this.dir.indexOf("/");
this.name = dir.substring(lastIndexOf);
}
public String getFirstImgPath() {
return firstImgPath;
}
public void setFirstImgPath(String firstImgPath) {
this.firstImgPath = firstImgPath;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="me.zcy.imagechoose.MainActivity">
<RelativeLayout
android:id="@+id/relative_layout"
android:layout_alignParentBottom="true"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:id="@+id/text_1"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/text_2"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<GridView
android:id="@+id/grid_view"
android:layout_above="@id/relative_layout"
android:stretchMode="columnWidth"
android:numColumns="3"
android:verticalSpacing="3dp"
android:horizontalSpacing="3dp"
android:listSelector="@android:color/transparent"
android:cacheColorHint="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/button"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="@mipmap/pictures_no"
android:id="@+id/id_item_image" />
<ImageButton
android:id="@+id/id_item_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:layout_alignParentRight="true"
android:layout_margin="3dp"
android:background="@null"
android:src="@mipmap/picture_unselected"
/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#ffffff"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:dividerHeight="1.0px"
android:divider="#eec679"
android:id="@+id/list_view"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/imageView"
android:background="@mipmap/pic_dir"
android:scaleType="centerCrop"
android:layout_marginLeft="35dp"
android:layout_marginStart="35dp"
android:layout_marginTop="27dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/dir_choose"
android:id="@+id/imageView2"
android:layout_alignParentRight="true"
android:layout_margin="30dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/linearLayout"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/imageView2"
android:layout_toRightOf="@+id/imageView">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/textView"
android:layout_marginTop="30dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/textView2"
android:layout_marginTop="50dp" />
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="200"
android:fromXDelta="0"
android:toXDelta="0"
android:fromYDelta="100%"
android:toYDelta="0"
/>
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="200"
android:fromXDelta="0"
android:toXDelta="0"
android:fromYDelta="0"
android:toYDelta="100%"
/>
</set>
<style name="dir">
<item name="android:windowEnterAnimation">@anim/anim_up</item>
<item name="android:windowExitAnimation">@anim/anim_down</item>
</style>
运行效果
