首页 > 编程技术 > android

安卓开发使用GestureDetector手势滑动界面

发布时间:2016-9-20 19:53

GestureDetector在android开发中使用到比较的多了,我们下面一起来看一篇关于安卓开发使用GestureDetector手势滑动界面的例子,具体细节如下所示.

用惯了苹果的人都知道在在APP中只需要手指左右滑动就可以进行页面的转换,但是在Android中大部分软件还只是使用返回键来进行界面的更替,其实Android很早很早以前就支持手势去更新操作,只是很多APP中没有使用到GestureDetector,下面就简单说说通过GestureDetector来进行界面的更替,下面只给出关键代码,直接使用即可。


GestureDetector  detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {//
@Override
public boolean onDown(MotionEvent e) {
return false;
}
 
@Override
public void onShowPress(MotionEvent e) {
 
}
 
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
 
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
 
@Override
public void onLongPress(MotionEvent e) {
 
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
if (e1.getX() - e2.getX() > 120) {//向左滑动,在这里可以进行界面间的更新,你想怎么干就怎么干
Intent intent = new Intent();
intent.setClass(MainActivity.this, Two.class);
startActivity(intent);
return true;
} else if (e1.getX() - e2.getX() < -120) {//向右滑动
MainActivity.this.finish();
return true;
}
return false;
}
});
 
@Override
public boolean onTouchEvent(MotionEvent event) {//一定要在activity中重写onTouchEvent方法才能使手势生效
detector.onTouchEvent(event);
return super.onTouchEvent(event);
}
 
上面是在正常情况下的滑动,当你在ListView等本身带有滑动的控件使用手势绝对会冲突,下面只给出最简单最粗暴的解决方式—— 改变系统的 onTouchEvent 事件的顺序,重写dispatchTouchEvent方法

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
 this.detector.onTouchEvent(ev);
 return super.dispatchTouchEvent(ev);
}

以上就是通过GestureDetector手势来进行界面间的转换,对动画研究透彻的童鞋可以在界面交替时加上动画效果!GestureDetector还有很多功能,有兴趣的可以继续研究

日期时间选择器在电脑中js有许多了,在android开发中也在库了,我们下面为各位整理了一些关于Android日期时间选择器的应用例子。

这里贴上一个Demo的源码,分享一下:

 代码如下 复制代码

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import com.bigkoo.pickerview.OptionsPopupWindow;
import com.bigkoo.pickerview.TimePopupWindow;
import com.bigkoo.pickerview.TimePopupWindow.OnTimeSelectListener;
import com.bigkoo.pickerview.TimePopupWindow.Type;
public class MainActivity extends Activity {

private TextView tvTime, tvOptions;
TimePopupWindow pwTime;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTime=(TextView) findViewById(R.id.tvTime);
//时间选择器
pwTime = new TimePopupWindow(this, Type.ALL);
//时间选择后回调
pwTime.setOnTimeSelectListener(new OnTimeSelectListener() {

@Override
public void onTimeSelect(Date date) {
tvTime.setText(getTime(date));
}
});
//弹出时间选择器
tvTime.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
pwTime.showAtLocation(tvTime, Gravity.BOTTOM, 0, 0,new Date());
}
});

}

public static String getTime(Date date) {
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm”);
return format.format(date);
}
}

 

当然只有上面一个源码文件肯定是不行的,分享这两个Demo的项目地址,大家可以去看一下。

 http://itlanbao.com/code/users/10000/20150911/Android-PickerView-master.rar

例子2

 代码如下 复制代码

自定义一个类:
/DateTimePicker/src/com/wwj/datetimepicker/DateTimePickDialogUtil.java

package com.wwj.datetimepicker;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.DatePicker;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TimePicker;
import android.widget.TimePicker.OnTimeChangedListener;

/**
 * 日期时间选择控件 使用方法: private EditText inputDate;//需要设置的日期时间文本编辑框 private String
 * initDateTime="2012年9月3日 14:44",//初始日期时间值 在点击事件中使用:
 * inputDate.setOnClickListener(new OnClickListener() {
 *
 * @Override public void onClick(View v) { DateTimePickDialogUtil
 *           dateTimePicKDialog=new
 *           DateTimePickDialogUtil(SinvestigateActivity.this,initDateTime);
 *           dateTimePicKDialog.dateTimePicKDialog(inputDate);
 *
 *           } });
 *
 * @author
 */
public class DateTimePickDialogUtil implements OnDateChangedListener,
  OnTimeChangedListener {
 private DatePicker datePicker;
 private TimePicker timePicker;
 private AlertDialog ad;
 private String dateTime;
 private String initDateTime;
 private Activity activity;

 /**
  * 日期时间弹出选择框构造函数
  *
  * @param activity
  *            :调用的父activity
  * @param initDateTime
  *            初始日期时间值,作为弹出窗口的标题和日期时间初始值
  */
 public DateTimePickDialogUtil(Activity activity, String initDateTime) {
  this.activity = activity;
  this.initDateTime = initDateTime;

 }

 public void init(DatePicker datePicker, TimePicker timePicker) {
  Calendar calendar = Calendar.getInstance();
  if (!(null == initDateTime || "".equals(initDateTime))) {
   calendar = this.getCalendarByInintData(initDateTime);
  } else {
   initDateTime = calendar.get(Calendar.YEAR) + "年"
     + calendar.get(Calendar.MONTH) + "月"
     + calendar.get(Calendar.DAY_OF_MONTH) + "日 "
     + calendar.get(Calendar.HOUR_OF_DAY) + ":"
     + calendar.get(Calendar.MINUTE);
  }

  datePicker.init(calendar.get(Calendar.YEAR),
    calendar.get(Calendar.MONTH),
    calendar.get(Calendar.DAY_OF_MONTH), this);
  timePicker.setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY));
  timePicker.setCurrentMinute(calendar.get(Calendar.MINUTE));
 }

 /**
  * 弹出日期时间选择框方法
  *
  * @param inputDate
  *            :为需要设置的日期时间文本编辑框
  * @return
  */
 public AlertDialog dateTimePicKDialog(final EditText inputDate) {
  LinearLayout dateTimeLayout = (LinearLayout) activity
    .getLayoutInflater().inflate(R.layout.common_datetime, null);
  datePicker = (DatePicker) dateTimeLayout.findViewById(R.id.datepicker);
  timePicker = (TimePicker) dateTimeLayout.findViewById(R.id.timepicker);
  init(datePicker, timePicker);
  timePicker.setIs24HourView(true);
  timePicker.setOnTimeChangedListener(this);

  ad = new AlertDialog.Builder(activity)
    .setTitle(initDateTime)
    .setView(dateTimeLayout)
    .setPositiveButton("设置", new DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialog, int whichButton) {
      inputDate.setText(dateTime);
     }
    })
    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialog, int whichButton) {
      inputDate.setText("");
     }
    }).show();

  onDateChanged(null, 0, 0, 0);
  return ad;
 }

 public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
  onDateChanged(null, 0, 0, 0);
 }

 public void onDateChanged(DatePicker view, int year, int monthOfYear,
   int dayOfMonth) {
  // 获得日历实例
  Calendar calendar = Calendar.getInstance();

  calendar.set(datePicker.getYear(), datePicker.getMonth(),
    datePicker.getDayOfMonth(), timePicker.getCurrentHour(),
    timePicker.getCurrentMinute());
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");

  dateTime = sdf.format(calendar.getTime());
  ad.setTitle(dateTime);
 }

 /**
  * 实现将初始日期时间2012年07月02日 16:45 拆分成年 月 日 时 分 秒,并赋值给calendar
  *
  * @param initDateTime
  *            初始日期时间值 字符串型
  * @return Calendar
  */
 private Calendar getCalendarByInintData(String initDateTime) {
  Calendar calendar = Calendar.getInstance();

  // 将初始日期时间2012年07月02日 16:45 拆分成年 月 日 时 分 秒
  String date = spliteString(initDateTime, "日", "index", "front"); // 日期
  String time = spliteString(initDateTime, "日", "index", "back"); // 时间

  String yearStr = spliteString(date, "年", "index", "front"); // 年份
  String monthAndDay = spliteString(date, "年", "index", "back"); // 月日

  String monthStr = spliteString(monthAndDay, "月", "index", "front"); // 月
  String dayStr = spliteString(monthAndDay, "月", "index", "back"); // 日

  String hourStr = spliteString(time, ":", "index", "front"); // 时
  String minuteStr = spliteString(time, ":", "index", "back"); // 分

  int currentYear = Integer.valueOf(yearStr.trim()).intValue();
  int currentMonth = Integer.valueOf(monthStr.trim()).intValue() - 1;
  int currentDay = Integer.valueOf(dayStr.trim()).intValue();
  int currentHour = Integer.valueOf(hourStr.trim()).intValue();
  int currentMinute = Integer.valueOf(minuteStr.trim()).intValue();

  calendar.set(currentYear, currentMonth, currentDay, currentHour,
    currentMinute);
  return calendar;
 }

 /**
  * 截取子串
  *
  * @param srcStr
  *            源串
  * @param pattern
  *            匹配模式
  * @param indexOrLast
  * @param frontOrBack
  * @return
  */
 public static String spliteString(String srcStr, String pattern,
   String indexOrLast, String frontOrBack) {
  String result = "";
  int loc = -1;
  if (indexOrLast.equalsIgnoreCase("index")) {
   loc = srcStr.indexOf(pattern); // 取得字符串第一次出现的位置
  } else {
   loc = srcStr.lastIndexOf(pattern); // 最后一个匹配串的位置
  }
  if (frontOrBack.equalsIgnoreCase("front")) {
   if (loc != -1)
    result = srcStr.substring(0, loc); // 截取子串
  } else {
   if (loc != -1)
    result = srcStr.substring(loc + 1, srcStr.length()); // 截取子串
  }
  return result;
 }

}


/DateTimePicker/src/com/wwj/datetimepicker/DateTimePickerActivity.java

package com.wwj.datetimepicker;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;

/**
 * 时间拾取器界面
 *
 * @author wwj_748
 *
 */
public class DateTimePickerActivity extends Activity {
 /** Called when the activity is first created. */
 private EditText startDateTime;
 private EditText endDateTime;

 private String initStartDateTime = "2013年9月3日 14:44"; // 初始化开始时间
 private String initEndDateTime = "2014年8月23日 17:44"; // 初始化结束时间

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  // 两个输入框
  startDateTime = (EditText) findViewById(R.id.inputDate);
  endDateTime = (EditText) findViewById(R.id.inputDate2);

  startDateTime.setText(initStartDateTime);
  endDateTime.setText(initEndDateTime);

  startDateTime.setOnClickListener(new OnClickListener() {
   public void onClick(View v) {

    DateTimePickDialogUtil dateTimePicKDialog = new DateTimePickDialogUtil(
      DateTimePickerActivity.this, initEndDateTime);
    dateTimePicKDialog.dateTimePicKDialog(startDateTime);

   }
  });

  endDateTime.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    DateTimePickDialogUtil dateTimePicKDialog = new DateTimePickDialogUtil(
      DateTimePickerActivity.this, initEndDateTime);
    dateTimePicKDialog.dateTimePicKDialog(endDateTime);
   }
  });
 }
}

自定义界面:
/DateTimePicker/res/layout/common_datetime.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <DatePicker
        android:id="@+id/datepicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:calendarViewShown="false" />

    <TimePicker
        android:id="@+id/timepicker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

Activity中经常会要做到返回顶部或一些功能了,今天我们就一起来看一个关于Android开发之Activity的中部或底部回到顶部的例子,具体操作如下.

我们浏览淘宝商品详情的时候会遇到回到顶部这个功能,下面就说说这个功能的简单实现


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:id="@+id/sc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<WebView
android:id="@+id/wb"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</WebView>
</LinearLayout>
</ScrollView>
 
<Button
android:id="@+id/bt"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/black"
android:layout_gravity="bottom"
android:text="点我向上"
android:textColor="#ffffff"
/>
 
</FrameLayout>

布局最外层使用FrameLayout,然后套上ScrollView,但是一定要注意ScrollView的高只能是wrap_content,要不然点击回到底部没效果。

代码如下

public class MainActivity extends AppCompatActivity {
private ScrollView sc;
private WebView wb;
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sc=(ScrollView)findViewById(R.id.sc);
wb=(WebView)findViewById(R.id.wb);
bt=(Button)findViewById(R.id.bt);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sc.post(new Runnable() {
@Override
public void run() {
sc.post(new Runnable() {
public void run() {
// 回到顶部
sc.fullScroll(ScrollView.FOCUS_UP);
}
});
}
});
}
});
initView();
}
 
private void initView() {
String url = "https://www.111cn.net/";
WebSettings webSettings = wb.getSettings();
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
webSettings.setJavaScriptEnabled(true); //设置WebView属性执行Javascript脚本
//设置可以访问文件
webSettings.setAllowFileAccess(true);
webSettings.setBuiltInZoomControls(false);// 设置是否显示缩放工具
wb.loadUrl(url);
wb.setWebViewClient(new WebViewClient());
 
}
}


2015-12-10_164558

实现效果如图,我这里是使用webView链接百度的网页,换成其他的控件也是一样的

安卓开发之Picasso框架了解不多了,小编今天来为各位介绍两个关于安卓开发之Picasso框架例子,希望这两个例子能够帮助到各位。

之前一直使用imageloader这个框架加载图片,觉得配置很麻烦,觉得使用Picasso这个框架。

什么是Picasso我就不多说了,大家可以去官网看,http://square.github.io/picasso/。

Picasso使用的方法汇总:

 代码如下 复制代码


Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
Picasso.with(context).load(url).into(view);
Picasso.with(context).load(url) .resize(50, 50).centerCrop().into(imageView)
//这里的placeholder将resource传入通过getResource.getDrawable取资源,所以可以是张图片也可以是color id
Picasso.with(context).load(url).placeholder(R.drawable.user_placeholder).error(R.drawable.user_placeholder_error).into
 
(imageView);
 
Picasso.with(context).load(R.drawable.landing_screen).into(imageView1);
Picasso.with(context).load("file:///android_asset/DvpvklR.png").into(imageView2);
Picasso.with(context).load(new File(...)).into(imageView3);
//这里显示notification的图片
Picasso.with(activity).load(Data.URLS[new Random().nextInt(Data.URLS.length)]).resizeDimen
 
(R.dimen.notification_icon_width_height,R.dimen.notification_icon_width_height).into(remoteViews, R.id.photo,
 
NOTIFICATION_ID, notification);
//这里是通过设置tag标签,就是当前传过来的context,这样就可以根据这个context tag来pause和resume显示了
Picasso.with(context).load(url).placeholder(R.drawable.placeholder).error(R.drawable.error).fit().tag(context).into
 
(view);
//监听onScrollStateChanged的时候调用执行
picasso.resumeTag(context);
picasso.pauseTag(context);
 
Picasso.with(context).load(contactUri).placeholder(R.drawable.contact_picture_placeholder).tag(context).into
 
(holder.icon);
//这个onpause方法里的这段代码还是很有意思的
@Override protected void onPause() {
    super.onPause();
    if (isFinishing()) {
      // Always cancel the request here, this is safe to call even if the image has been loaded.
      // This ensures that the anonymous callback we have does not prevent the activity from
      // being garbage collected. It also prevents our callback from getting invoked even after the
      // activity has finished.
      Picasso.with(this).cancelRequest(imageView);
    }
  }
// Trigger the download of the URL asynchronously into the image view.
    Picasso.with(context)
        .load(url)
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.error)
        .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
        .centerInside()
        .tag(context)
        .into(holder.image);
//Picasso.with使用的是单例模式

Picasso.with(this).cancelTag(this);

然后呢,Picasso还提供了debug的标示,调用picasso的setIndicatorsEnabled方法,true是debug模式,跟踪代码其实就是在最后生成的
PicassoDrawable类的ondraw里绘制了个左上角小三角,根据

 代码如下 复制代码

public enum LoadedFrom {
MEMORY(Color.GREEN),
DISK(Color.BLUE),
NETWORK(Color.RED);

枚举里的不同值标示不同加载来源,这对分析图片加载有好处。

在Picasso.with()的时候会将执行所需的所有必备元素创建出来,如缓存cache、执行executorService、调度dispatch等,在load()时创建Request,在into()中创建action、bitmapHunter,并最终交给dispatcher执行。


Picasso创建圆形图像

上篇介绍了Picasso这个框架,git地址是https://github.com/square/picasso。怎么实现各种各样的图片样式呢,在Picasso里提供了Transformation这个接口,我们可以自己实现。下面是一个实现圆形图片的demo;

 代码如下 复制代码

public class CircleTransform implements Transformation {
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
 
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
 
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
 
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
 
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap,
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
 
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
 
squaredBitmap.recycle();
return bitmap;
}
 
@Override
public String key() {
return "circle";
}
}

使用它:

Picasso.with(activity).load(mayorShipImageLink).transform(new CircleTransform()).into(ImageView);
 

下面我们一起来看一篇关于android studio、eclipse分别导入运行qq Android sdk 第三方登录的例子,希望此例子能够帮助到大家。

这里我是先导入eclipse,然后到处为gradle buid files ,再导入 android studio。
 
要是对gradle编译脚本熟悉的,可以直接导入,然后手动写gradle的配置文件。

1.下载qq android sdk

选择:

1.jpg

2. 解压后得到的目录结构为:

1.jpg

3.将上面的sample文件夹导入的Eclipse,目录结构如下:

1.jpg

修改项目的编码为UTF-8:

1.jpg

4.修复库依赖关系

 代码显示有错误,那是因为我们没有将qq的sdk jar包放到libs目录下。

点击项目右键&mdash;&mdash;Properities&mdash;&mdash;Android,将错误的依赖关系删除:

1.jpg

5.导入sdk jar库

将下载的qq android sdk包下的 jar/目录下的 两个jar包 复制到 项目的libs目录:

1.jpg

 

此时项目的目录结构如下:

1.jpg

然后clean  ,再重新编译。代码就没有报错了。

6.将项目导入到Android studio

最关键的一步,如何将eclipse中的项目导入到Android studio中:

右键项目,选择&ldquo;export&rdquo;&mdash;&mdash;android&mdash;&mdash;generate gradle build files &mdash;&mdash;然后选中要到处都项目,得到导出的项目包。

再将得到的项目包,导入到android studio中。会提示报错,我们需要将项目根目录的build.gradle文件中的(可能你的android studio使用的gradle版本和gradle插件版本与我的有不同,建议更改成自己的所使用的版本)


dependencies {
    classpath 'com.android.tools.build:gradle:0.12+'
}
改为我们使用的新到gradle插件版本:


dependencies {
    classpath 'com.android.tools.build:gradle:1.3.0'
}

注意:如果有可能,可能还需要改项目根目录下/gradle/wrapper/gradle-wrapper.properties中的

7.重新编译运行

改完后,点击&ldquo;Sync now&rdquo;,重新编译项目,就会发现项目没有报错,在模拟器中测试,一切正常。
android studio版本的QQ sdk demo下载(最新版)

标签:[!--infotagslink--]

您可能感兴趣的文章: