1.androidͼƬ?片轮ֲ?Դ??
2.android使用ViewPager实现轮播效果教程
3.å®åViewFlipperç使ç¨è¯¦è§£
androidͼƬ?ֲ?Դ??
Google相册,以其强大的播源功能,再次升级,片轮带来一项重要的播源用户体验优化——重新定位的选项行。这一改变,片轮对于现代屏幕尺寸的播源下载类网页源码手机用户来说,无疑是片轮个福音,让快速处理照片和视频变得更加便捷。播源在稳定版5..0.中,片轮"按住选择"功能现在位于屏幕底部,播源而非之前的片轮右上角。
新的播源设计考虑到了操作的直观性,只需轻轻一按,片轮就能批量共享、播源存档或删除,片轮无需切换手部操作。Android Police指出,雷达软件源码尽管目前还未全面普及,但这一变化已经在稳定版中亮相。
底部的选项栏不仅包括常用联系人,还有你最近编辑的相册轮播,轻轻一点,就能快速添加选中的内容。左上角的计数器实时显示你选择的或视频数量,虽然切换到全新布局可能会有些许不适应,游戏源码 工具但它确实受到了欢迎,尤其是在大屏手机用户中。
值得一提的是,"按住选择"的功能现在更加丰富,底部选项包括共享、存入特定相册、移至垃圾箱、存档、美图的源码直接从设备删除、编辑位置,甚至还有锁定文件夹,满足了用户对隐私和组织的更多需求。在iOS版本中,这个功能早已存在,因此Android用户也即将享受到这一便利。
谷歌近期的传奇源码开放更新中,"Locked Folder"功能的加入是另一大亮点,为照片安全提供了额外保障,内容存储在本地,无需担心云同步的问题。对于Pixel设备用户来说,这个备受期待的功能终于面向所有用户开放了。
总之,谷歌相册的最新更新无疑在提升用户操作效率和隐私保护上迈出了一大步,我们期待更多这样的创新,让用户的照片管理体验更加顺畅和智能。如果你已经在Android设备上体验到了新的选项行,请务必分享你的使用感受。
android使用ViewPager实现轮播效果教程
ViewPager:一个可以实现视图左右滑动切换的控件。
ViewPager的基本使用:
ViewPager的视图需要通过PagerAdapter来实现显示。
PagerAdapter的主要方法:
● getCount 视图的数量
● instantiateItem 添加视图
● destroyItem 销毁视图
● isViewFromObject 是否由对象创建视图
ViewPager的常用方法:
setAdapter 设置适配器
addOnPageChangeListener 监听页面切换的状态
setCurrentItem 设置当前页面的索引
实现广告轮播
技术点分析:
1、网络连接
2、JSON解析
3、ViewPager的初始化
4、的异步加载
5、圆点指示器的实现
使用selector+shape实现圆点
动态创建ImageView添加到集合中,同时添加到布局中
在ViewPager切换事件中,切换圆点状态
6、自动切换效果
使用Handler的post方法,定时执行代码
资源文件:
mydot.xml //创建圆点资源,放在drawable文件下
布局文件:
activity_main.xml
xmlns:tools=".edu.huse.banner_re.util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/
*** 加载的工具类
* @author xray
*
*/
public class ImageLoader {
/
*** 加载完成的回调接口
* 添加URL参数,用于做错位判断
*/
public interface OnImageLoadListener{
//完成加载
void onImageLoadComplete(String url, Bitmap bitmap);
}
private OnImageLoadListener mListener;
/
*** 启动加载任务
* @param urlStr
* @param listener
*/
public void loadImage(String urlStr,OnImageLoadListener listener){
this.mListener = listener;
new ImageLoadTask().execute(urlStr);
}
/
*** 加载任务
* @author xray
*
*/
class ImageLoadTask extends AsyncTask
@Override
protected UrlAndBitmap doInBackground(String... params) {
try {
//创建URL,指定地址
URL url = new URL(params[0]);
//打开连接获得HttpURLConnection对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//获得文件输入流
InputStream stream = conn.getInputStream();
//把输入流转换为
Bitmap bmp = BitmapFactory.decodeStream(stream);
//关闭流
stream.close();
return new UrlAndBitmap(params[0],bmp);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//包装地址和
class UrlAndBitmap{
String url;
Bitmap bitmap;
public UrlAndBitmap(String url, Bitmap bitmap) {
this.url = url;
this.bitmap = bitmap;
}
}
@Override
protected void onPostExecute(UrlAndBitmap result) {
//进行接口回调
if(mListener != null){
mListener.onImageLoadComplete(result.url,result.bitmap);
}
}
}
}
JSONLoader.java
//读取服务器json
package cn.edu.huse.banner_re.util;
import android.os.AsyncTask;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/
*** 读取服务器JSON的工具类
* @author xray
*
*/
public class JSONLoader {
public interface OnJSONLoadListener{
void onJSONLoadComplete(String json);
}
private OnJSONLoadListener mListener;
public void loadJSON(String urlStr,OnJSONLoadListener listener){
this.mListener = listener;
new JSONLoadTask().execute(urlStr);
}
class JSONLoadTask extends AsyncTask
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream inputStream = conn.getInputStream();
byte[] buffer = new byte[];
int len = 0;
//StringBuffer 线程安全,性能低 VS StringBuilder 线程不安全,性能高
StringBuilder strB = new StringBuilder();
while((len = inputStream.read(buffer)) != -1){
//将字节码转换为String
String str = new String(buffer,0,len);
strB.append(str);
}
inputStream.close();
return strB.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
if(mListener != null){
mListener.onJSONLoadComplete(result);
}
}
}
}
MyViewPagerAdapter.java
package cn.edu.huse.banner_re.adapter;
import java.util.List;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
/
*** 轮播的适配器
* @author Lenovo
*
*/
public class MyViewPagerAdapter extends PagerAdapter {
private List mData;
public MyViewPagerAdapter(List mData) {
this.mData = mData;
}
//返回视图的数量
@Override
public int getCount() {
return mData.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
//销毁
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mData.get(position));
}
//添加
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mData.get(position));
return mData.get(position);
}
}
MainActivity.java
package cn.edu.huse.banner_re;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioButton;
import cn.edu.huse.banner_re.adapter.MyViewPagerAdapter;
import cn.edu.huse.banner_re.util.ImageLoader;
import cn.edu.huse.banner_re.util.ImageLoader.OnImageLoadListener;
import cn.edu.huse.banner_re.util.JSONLoader;
import cn.edu.huse.banner_re.util.JSONLoader.OnJSONLoadListener;
public class MainActivity extends Activity implements OnClickListener{
public static final String URL_GIFT = "/majax.action?method=getGiftListpageno=1";
public static final String URL_BASE = "";
private ListView mLv;
//放置圆点的布局
private LinearLayout mLayout;
private ViewPager mPager;
//保存viewpager上的集合
private List mImageViews;
//保存圆点的集合
private List mDotViews;
//当前
private ImageView mDotView;
//当前下标
private int mIndex;
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化viewpager
initViewPager();
}
private void initViewPager() {
new JSONLoader().loadJSON(URL_GIFT, new OnJSONLoadListener() {
@Override
public void onJSONLoadComplete(String json) {
//得到的地址
List list = josnPare(json);
//初始化主控件
initView();
//将显示到viewpager中
initImageViews(list);
//为ViewPager设置适配器
mPager.setAdapter(new MyViewPagerAdapter(mImageViews));
//加载圆点
initDot(mImageViews.size());
//实现的轮播
mPager.postDelayed(new Runnable() {
@Override
public void run() {
//下标自动++
mIndex++;
//当下标到最后时,就重新来过
if(mIndex = mImageViews.size()){
mIndex = 0;
}
//设置
mPager.setCurrentItem(mIndex);
//重复调用
mHandler.postDelayed(this, );
}
}, );
//添加页码滑动的监听,实现圆点的切换
mPager.setOnPageChangeListener(new OnPageChangeListener() {
//页选中后调用
@Override
public void onPageSelected(int arg0) {
//改变原来的圆点的状态
mDotView.setEnabled(true);
//更新当前的圆点
mDotView = mDotViews.get(arg0);
//将当前选中的圆点设为选中状态
mDotView.setEnabled(false);
//更新下标
mIndex = arg0;
}
//滑动中途调用
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
//页面滑动状态修改
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
});
}
/**获取圆点函数
* @param count viewpager上的数量
*/
private void initDot(int count){
mDotViews = new ArrayList();
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
//设置边距
params.setMargins(5, 0, 5, 0);
for(int i = 0; i count; i++){
ImageView image = new ImageView(this);
//设置圆点
image.setImageResource(R.drawable.mydot);
//设置的位置,方便后面的取值
image.setTag(i);
//设置监听
image.setOnClickListener(this);
//添加到布局中
mLayout.addView(image, params);
//将圆点保存到集合中
mDotViews.add(image);
}
mDotView = mDotViews.get(0);
mDotView.setEnabled(false);
}
/
***显示的函数
*/
private void initImageViews(List list) {
mImageViews = new ArrayList();
for(String str : list){
final ImageView imageView = new ImageView(this);
//设置默认
imageView.setImageResource(R.drawable.ic_launcher);
new ImageLoader().loadImage(URL_BASE+str, new OnImageLoadListener() {
@Override
public void onImageLoadComplete(String url, Bitmap bitmap) {
if(bitmap != null){
imageView.setImageBitmap(bitmap);
}
}
});
//将ImageView保存到集合中
mImageViews.add(imageView);
}
}
/
*** JSON解析获取的地址
* @param url
* @return
*/
private List josnPare(String url){
List list = new ArrayList();
try {
JSONObject jobj = new JSONObject(url);
JSONArray array = jobj.getJSONArray("ad");
for(int i = 0; i array.length(); i++){
JSONObject obj = (JSONObject) array.get(i);
list.add(obj.getString("iconurl"));
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/
*** 初始化控件
*/
private void initView() {
//找到控件
mLv = (ListView) findViewById(R.id.lv_list);
View view = LayoutInflater.from(this).inflate(R.layout.activity_banner, null);
mPager = (ViewPager)view.findViewById(R.id.vp_image);
//圆点布局
mLayout = (LinearLayout)view.findViewById(R.id.layout);
//模拟数据
List mList = new ArrayList();
for(int i = 0; i ; i++){
mList.add("条目--"+i);
}
//创建适配器
ArrayAdapter mAdapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1,
android.R.id.text1,
mList);
//设置头部视图
mLv.addHeaderView(view);
//设置适配器
mLv.setAdapter(mAdapter);
/*//圆点布局
mLayout = (LinearLayout)findViewById(R.id.layout);*/
}
/
*** 圆点的监听事件
*/
@Override
public void onClick(View arg0) {
//获取该圆点的位置
int index = Integer.parseInt(arg0.getTag().toString());
//将viewpager的显示成下标为index的
mPager.setCurrentItem(index);
//将原来的设置成默认值
mDotView.setEnabled(true);
//保存新的值
mDotView = (ImageView) arg0;
//将新的值改变成false
mDotView.setEnabled(false);
//更新下标
mIndex = index;
}
}
注意:因为这里用到了json解析,需要用到联网操作,一定要写上上网的权限:
运行效果:
å®åViewFlipperç使ç¨è¯¦è§£
ViewFlipperçä»ç»å使ç¨
ViewFlipperæ¯Androidèªå¸¦çä¸ä¸ªå¤é¡µé¢ç®¡çæ§ä»¶ï¼ä¸å¯ä»¥èªå¨ææ¾ï¼åViewPagerä¸åï¼ViewPageræ¯ä¸é¡µé¡µçï¼èViewFlipperåæ¯ä¸å±å±çï¼åViewPagerä¸æ ·ï¼å¾å¤æ¶åï¼ç¨æ¥å®ç°è¿å ¥åºç¨åçå¼å¯¼é¡µï¼æè ç¨äºå¾çè½®æã
ä¸ã常ç¨çå±æ§åæ¹æ³å±æ§ï¼
android:inAnimation//设置ViewæImageViewè¿å ¥å±å¹æ¶ä½¿ç¨çå¨ç»android:outAnimation//设置ViewæImageViewéåºå±å¹æ¶ä½¿ç¨çå¨ç»android:flipInterval//设置ViewæImageViewä¹é´åæ¢çæ¶é´é´é常ç¨æ¹æ³ï¼
setInAnimationï¼è®¾ç½®ViewæImageViewè¿å ¥å±å¹æ¶ä½¿ç¨çå¨ç»
setOutAnimationï¼è®¾ç½®ViewæImageViewéåºå±å¹æ¶ä½¿ç¨çå¨ç»
showNextï¼è°ç¨è¯¥æ¹æ³æ¥æ¾ç¤ºViewFlipperéçä¸ä¸ä¸ªViewæImageView
showPreviousï¼è°ç¨è¯¥æ¹æ³æ¥æ¾ç¤ºViewFlipperçä¸ä¸ä¸ªViewæImageView
setFilpIntervalï¼è®¾ç½®ViewæImageViewä¹é´åæ¢çæ¶é´é´é
startFlippingï¼ä½¿ç¨ä¸é¢è®¾ç½®çæ¶é´é´éæ¥å¼å§åæ¢ææçViewæImageViewï¼åæ¢ä¼å¾ªç¯è¿è¡
stopFlippingï¼åæ¢ViewæImageViewåæ¢
äºãéæå¯¼å ¥è¿è¡ææï¼
å®ç°è¿ä¸ªææé常çç®å
ç¼åviewpfilper.xmlå¸å±æ件
<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ViewFlipperandroid:id="@+id/flipper"android:layout_width="match_parent"android:layout_height="match_parent"android:flipInterval=""><ImageViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:scaleType="centerCrop"android:src="@drawable/tx1"/><ImageViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:scaleType="centerCrop"android:src="@drawable/tx2"/><ImageViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:scaleType="centerCrop"android:src="@drawable/tx3"/><ImageViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:scaleType="centerCrop"android:src="@drawable/tx4"/></ViewFlipper></LinearLayout>ç¼åViewFliperæ´»å¨ä»£ç
publicclassViewpFilperextendsAppCompatActivity{ privateViewFlippermFilper;@OverrideprotectedvoidonCreate(@NullableBundlesavedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.viewpfilper);mFilper=findViewById(R.id.flipper);mFilper.startFlipping();}}å½æ们添å äºå¨ç»çæ¶åï¼ææå°±åæè¿æ ·äºï¼
æ们å¨resç®å½ä¸æ°å»ºä¸ä¸ªanimæ件夹ï¼åæ°å»ºright_in.xmlãright_out.xmlåæ¾å¨ç»
right_in.xml
<?xmlversion="1.0"encoding="utf-8"?><setxmlns:android="/apk/res/android"><translateandroid:duration=""android:fromXDelta="%p"android:toXDelta="0"/></set>right_out.xml
<?xmlversion="1.0"encoding="utf-8"?><setxmlns:android="/apk/res/android"><translateandroid:duration=""android:fromXDelta="0"android:toXDelta="-%p"/></set>æåå¨viewpfilper.xmlå¸å±æ件ä¸å¼ç¨å°±è¡
äºãå¨æå¯¼å ¥ï¼æ¯ææå¿æ»å¨ï¼æ们å¯ä»¥éè¿å¯¹æå¿ççå¬ï¼èªç±çæ»å¨ãä¸æ»å¨ä¹å¯ä»¥èªå·±å¨ãè½®æå¾å°±æ¯è¿æ ·ææã
è¿è¡ææï¼
æ们å¨ä¸ä¸ä¸ªä»£ç çåºç¡ä¸ä¿®æ¹ã
å¨animæ件ä¸åæ·»å left_in.xmlãleft_out.xmlï¼è®©æ们左å³æ»å¨æ´å çæµç
left_in.xml
<?xmlversion="1.0"encoding="utf-8"?><setxmlns:android="/apk/res/android"><translateandroid:duration=""android:fromXDelta="-%p"android:toXDelta="0"/></set>left_in.xml
<?xmlversion="1.0"encoding="utf-8"?><setxmlns:android="/apk/res/android"><translateandroid:duration=""android:fromXDelta="0"android:toXDelta="%p"/></set>å°right_in.xmlãright_out.xmlçå±æ§Android:duration=""设置为ï¼åå·¦å³è¿åºçä¸æ ·ï¼ä¸ç¶æ»å¨ä¼å¾æ ¢ï¼è¿æå·¦å³æ»å¨ä¸åè°
GestureDetectoræå¿æ£æµå¨ï¼çå¬æ们çæå¿å¨ä½
并ä¸éåonTouchEvent触åMyGestureListeneréçæ¹æ³
å¸å±æ件ä¸å
ç¼åViewFliperActivityçjava代ç
publicclassViewpFilperextendsAppCompatActivity{ privateViewFlippermFilper;privateGestureDetectormDetector;//æå¿æ¢æµå¨privateMyGestureListenermMyGestureListener;@OverrideprotectedvoidonCreate(@NullableBundlesavedInstanceState){ super.onCreate(savedInstanceState);setContentView(R.layout.viewpfilper);mFilper=findViewById(R.id.flipper);//å®ä¾åSimpleOnGestureListenerä¸GestureDetector对象mMyGestureListener=newMyGestureListener();mDetector=newGestureDetector(this,mMyGestureListener);mFilper.startFlipping();}@OverridepublicbooleanonTouchEvent(MotionEventevent){ returnmDetector.onTouchEvent(event);}privateclassMyGestureListenerextendsGestureDetector.SimpleOnGestureListener{ privatefinalstaticintMIN_MOVE=;//æå°è·ç¦»//OnFlingä¸æ ¹æ®Xè½´æ¹å移å¨çè·ç¦»åé度æ¥å¤æå½åç¨æ·æ¯åå·¦æ»è¿æ¯åå³æ»ï¼//ä»èå©ç¨showPrevious()æè showNext()æ¥æ¾ç¤ºä¸ä¸å¼ æè ä¸ä¸å¼ å¾ç@OverridepublicbooleanonFling(MotionEvente1,MotionEvente2,floatvelocityX,floatvelocityY){ if(e1.getX()-e2.getX()>MIN_MOVE){ mFilper.setInAnimation(getApplicationContext(),R.anim.right_in);mFilper.setOutAnimation(getApplicationContext(),R.anim.right_out);mFilper.showNext();}elseif(e2.getX()-e1.getX()>MIN_MOVE){ mFilper.setInAnimation(getApplicationContext(),R.anim.left_in);mFilper.setOutAnimation(getApplicationContext(),R.anim.left_out);mFilper.showPrevious();}returntrue;}}}å°è¿éViewFlipperçåºæ¬ä½¿ç¨å°±å·®ä¸å¤äºã
2024-11-30 00:59
2024-11-30 00:12
2024-11-29 23:48
2024-11-29 23:23
2024-11-29 23:04
2024-11-29 22:28