一、線程中使用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>
運行效果
