首先上效果图

第一张图是进入该界面的效果,顶部是一个viewpager,下面每个块都是自定义的view HomeButton,第二张图是点击右边第一个方块的效果,点击时方块整体有收缩的效果,中间会显示手印,手指抬起时又恢复原样。

在之前的一篇文章 Android view绘制流程已经详细介绍了view的绘制流程,这里不多说,除了知道view的绘制流程外,我们还应该落实到实处,要做好自定义view当然要熟悉drawable和canvas,多在这两块下功夫,然后可能需要加上一些小技巧,本文的例子主要是用canvas和matrix加上动画做的效果,这里贴一下关于Matrix的介绍。

关于Matrix

Matrix的对图像的处理可分为四类基本变换:
Translate 平移变换
Rotate 旋转变换
Scale 缩放变换
Skew 错切变换

除平移变换(Translate)外,旋转变换(Rotate)、缩放变换(Scale)和错切变换(Skew)都可以围绕一个中心点来进行,如果不指定,在默认情况下是围绕(0, 0)来进行相应的变换的。

针对每种变换,Android提供了pre、set和post三种操作方式。其中
set用于设置Matrix中的矩阵值。
pre是先乘,post是后乘,因为矩阵的乘法不满足交换律,因此先乘、后乘必须要严格区分。先乘相当于矩阵运算中的右乘。后乘相当于矩阵运算中的左乘。

事实上,图像处理时,矩阵的运算是从右边往左边方向进行运算的。这就形成了越在右边的矩阵(右乘),越先运算(先乘),反之亦然。

post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来进行多种变换。例如,需要将图片旋转60度,然后平移到(100,,100)的地方,那么可以这样做:

Matrix m = new Matrix();
m.postRotate(60);
m.postTranslate(100,100);

这样就达到了效果。
pre是前乘,参数给出的矩阵乘以当前的矩阵。上面的例子,如果使用pre的话就要这样做:

Matrix m = new Matrix();
m.setTranslate(100,100);
m.preRotate(60);

主要代码

HomeButton类,自定义view继承ImageView

package com.chm.test.view;import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;import com.chm.test.R;
import com.chm.test.myInterface.HomeClickListener;
import com.chm.test.utils.BitmapUtils;public class HomeButton extends ImageView {private Bitmap bitmap;private Bitmap home_flight;private Bitmap label_new;private int state = 0; //是否按下private int color;private float textsize;private boolean big;private int home;private String text;private int screenW;private int screenH;//点击事件private HomeClickListener listener = null;private int[] colors = {getResources().getColor(R.color.red),getResources().getColor(R.color.orange),getResources().getColor(R.color.blue),getResources().getColor(R.color.purple),getResources().getColor(R.color.air),getResources().getColor(R.color.texi),getResources().getColor(R.color.jingdian)};private Bitmap[] bitmaps = {BitmapFactory.decodeResource(getResources(), R.drawable.home_hotel),BitmapFactory.decodeResource(getResources(),R.drawable.home_groupbuy),BitmapFactory.decodeResource(getResources(), R.drawable.home_train),BitmapFactory.decodeResource(getResources(),R.drawable.home_lastmin),BitmapFactory.decodeResource(getResources(), R.drawable.home_flight),BitmapFactory.decodeResource(getResources(), R.drawable.home_car),BitmapFactory.decodeResource(getResources(),R.drawable.home_scenery)};public HomeButton(Context context) {super(context);}public HomeButton(Context context, AttributeSet attrs) {super(context, attrs);bitmap = BitmapUtils.zoomImage(BitmapFactory.decodeResource(getResources(), R.drawable.fingerprint), 127, 122);label_new = BitmapFactory.decodeResource(getResources(), R.drawable.label_new);TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.HomeButton);color = typedArray.getInt(R.styleable.HomeButton_backcolor, 0);textsize = typedArray.getDimension(R.styleable.HomeButton_textSize, 24);big = typedArray.getBoolean(R.styleable.HomeButton_big, true);home = typedArray.getInt(R.styleable.HomeButton_home, 0);text = typedArray.getString(R.styleable.HomeButton_text);System.out.println("color:" + color + " textsize:" + textsize + " big:"+ big + " home:" + home);home_flight = bitmaps[home];screenW = ((Activity) context).getWindow().getWindowManager().getDefaultDisplay().getWidth() / 2 - 16;if (big) {screenH = screenW;} else {screenH = screenW / 2 - 4;}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 重新设置View大小setMeasuredDimension(screenW, screenH);}/** orange 2182F7 light red 7359EF 紫 B551A5 Blue CE8A39 air CEBE00 texi* 9CAA00 jingdian 00AA73*/@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(colors[color]);Paint paint = new Paint();paint.setColor(Color.WHITE);paint.setTextSize(24);if (big) {Matrix matrix = new Matrix();matrix.postTranslate(this.getWidth() / 2 - home_flight.getWidth()/ 2, this.getHeight() / 2 - home_flight.getHeight() / 2);canvas.drawText(text, 10, 40, paint);canvas.drawBitmap(home_flight, matrix, paint);} else {Matrix matrix_small = new Matrix();matrix_small.postTranslate(10, this.getHeight() / 2 - home_flight.getHeight() / 2);canvas.drawBitmap(home_flight, matrix_small, new Paint());if (home == 3) {paint.setTextSize(16);canvas.drawText("夜宵酒店", home_flight.getWidth() + 20, this.getHeight() / 2 - home_flight.getHeight() / 2 + 10, paint);canvas.drawText("加载中...", home_flight.getWidth() + 20, this.getHeight() / 2 + home_flight.getHeight() / 2, paint);} else if (home == 5) {paint.setTextSize(16);canvas.drawText("送机", home_flight.getWidth() + 20, this.getHeight() / 2 - home_flight.getHeight() / 2 + 10, paint);canvas.drawText("免费叫出租", home_flight.getWidth() + 20, this.getHeight() / 2 + home_flight.getHeight() / 2, paint);} else {canvas.drawText(text, home_flight.getWidth() + 20, this.getHeight() / 2 + home_flight.getHeight() / 2, paint);}if (home == 6) {Matrix matrix_new = new Matrix();matrix_new.postTranslate(screenW - label_new.getWidth(), 0);canvas.drawBitmap(label_new, matrix_new, new Paint());}}//按下if (state == 1) {Matrix matrix2 = new Matrix();matrix2.postTranslate(this.getWidth() / 2 - bitmap.getWidth() / 2,this.getHeight() / 2 - bitmap.getHeight() / 2);canvas.drawBitmap(bitmap, matrix2, new Paint());}}@Overridepublic boolean onTouchEvent(MotionEvent event) {float start = 1.0f;float end = 0.95f;Animation scaleAnimation = new ScaleAnimation(start, end, start, end,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);Animation endAnimation = new ScaleAnimation(end, start, end, start,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);scaleAnimation.setDuration(200);scaleAnimation.setFillAfter(true);endAnimation.setDuration(200);endAnimation.setFillAfter(true);switch (event.getAction()) {case MotionEvent.ACTION_DOWN:this.startAnimation(scaleAnimation);state = 1;invalidate();break;case MotionEvent.ACTION_UP:this.startAnimation(endAnimation);state = 0;invalidate();if (listener != null) {listener.onclick();}break;// 滑动出去不会调用action_up,调用action_cancelcase MotionEvent.ACTION_CANCEL:this.startAnimation(endAnimation);state = 0;invalidate();break;}// 不返回true,Action_up就响应不了return true;}/*** 加入响应事件** @param clickListener*/public void setOnHomeClick(HomeClickListener clickListener) {this.listener = clickListener;}}

HomeClickListener接口

public interface HomeClickListener {public void onclick();
}

HotelActivity类

package com.chm.test;import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;import com.chm.mylibrary.BaseActivity;
import com.chm.test.adapter.ViewPagerAdapter;
import com.chm.test.myInterface.HomeClickListener;
import com.chm.test.utils.BitmapUtils;
import com.chm.test.view.HomeButton;import java.util.ArrayList;
import java.util.List;public class HotelActivity extends BaseActivity implements View.OnClickListener,ViewPager.OnPageChangeListener {private ViewPager vp;private ViewPagerAdapter vpAdapter;private List<View> views;private int width;private int height;private RelativeLayout relativeLayout;// 引导图片资源private static final int[] pics = { R.drawable.home1, R.drawable.home2,R.drawable.home3, R.drawable.home4 };// 底部小店图片private ImageView[] dots;// 记录当前选中位置private int currentIndex;private View view;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.index);HomeButton button  = (HomeButton) findViewById(R.id.hotel);button.setOnHomeClick(new HomeClickListener() {@Overridepublic void onclick() {Intent intent     =new Intent();intent.setClass(HotelActivity.this, HotelActivity.class);startActivity(intent);}});//等到屏幕的大小width  = this.getWindowManager().getDefaultDisplay().getWidth();//以670*240的图片为例,正常中不要这样用height =width*240/670;relativeLayout       =(RelativeLayout) findViewById(R.id.relative);LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) relativeLayout.getLayoutParams();layoutParams.width       =width;layoutParams.height       =height;relativeLayout.setLayoutParams(layoutParams);views = new ArrayList<View>();LinearLayout.LayoutParams mParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);// 初始化引导图片列表for (int i = 0; i < pics.length; i++) {ImageView iv = new ImageView(this);iv.setLayoutParams(mParams);//改变大小
//       iv.setImageResource(pics[i]);iv.setImageBitmap(BitmapUtils.zoomImage(BitmapFactory.decodeResource(getResources(), pics[i]), width, height));views.add(iv);}vp = (ViewPager) findViewById(R.id.viewpager);RelativeLayout.LayoutParams params    = new RelativeLayout.LayoutParams(width, height);params.leftMargin=10;params.topMargin=10;params.rightMargin=10;vp.setLayoutParams(params);// 初始化AdaptervpAdapter = new ViewPagerAdapter(views);vp.setAdapter(vpAdapter);// 绑定回调vp.setOnPageChangeListener(this);// 初始化底部小点initDots();}private void initDots() {LinearLayout ll = (LinearLayout) findViewById(R.id.ll);dots = new ImageView[pics.length];// 循环取得小点图片for (int i = 0; i < pics.length; i++) {dots[i] = (ImageView) ll.getChildAt(i);dots[i].setEnabled(true);// 都设为灰色dots[i].setOnClickListener(this);dots[i].setTag(i);// 设置位置tag,方便取出与当前位置对应}currentIndex = 0;dots[currentIndex].setEnabled(false);// 设置为白色,即选中状态}/*** 设置当前的引导页*/private void setCurView(int position) {if (position < 0 || position >= pics.length) {return;}vp.setCurrentItem(position);}/*** 这只当前引导小点的选中*/private void setCurDot(int positon) {if (positon < 0 || positon > pics.length - 1 || currentIndex == positon) {return;}dots[positon].setEnabled(false);dots[currentIndex].setEnabled(true);currentIndex = positon;}// 当滑动状态改变时调用@Overridepublic void onPageScrollStateChanged(int arg0) {}// 当当前页面被滑动时调用@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {vp.requestDisallowInterceptTouchEvent(true);}// 当新的页面被选中时调用@Overridepublic void onPageSelected(int arg0) {// 设置底部小点选中状态setCurDot(arg0);}@Overridepublic void onClick(View view) {int position = (Integer) view.getTag();setCurView(position);setCurDot(position);}}

布局文件index.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:ptr="http://schemas.android.com/apk/res-auto"android:layout_width="fill_parent"android:layout_height="wrap_content" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="#545454"android:orientation="vertical" ><RelativeLayoutandroid:id="@+id/relative"android:layout_width="match_parent"android:layout_height="wrap_content" ><android.support.v4.view.ViewPagerandroid:id="@+id/viewpager"android:layout_width="fill_parent"android:layout_height="match_parent"android:layout_alignParentTop="true"android:layout_marginLeft="8dp"android:layout_marginRight="8dp" /><LinearLayoutandroid:id="@+id/ll"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:orientation="horizontal" ><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:clickable="true"android:padding="15.0dip"android:src="@drawable/dot" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:clickable="true"android:padding="15.0dip"android:src="@drawable/dot" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:clickable="true"android:padding="15.0dip"android:src="@drawable/dot" /><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:clickable="true"android:padding="15.0dip"android:src="@drawable/dot" /></LinearLayout></RelativeLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="8dp"android:orientation="vertical" ><com.chm.test.view.HomeButtonandroid:id="@+id/hotel"android:layout_width="300dp"android:layout_height="300dp"android:background="#aaa"ptr:backcolor="0"ptr:big="true"ptr:home="0"ptr:text="酒店"ptr:textSize="24sp" /><com.chm.test.view.HomeButtonandroid:layout_width="200dp"android:layout_height="200dp"android:layout_marginTop="8dp"android:background="#aaa"ptr:backcolor="1"ptr:big="true"ptr:home="1"ptr:text="团购"ptr:textSize="24sp" /><com.chm.test.view.HomeButtonandroid:layout_width="200dp"android:layout_height="200dp"android:layout_marginTop="8dp"android:background="#aaa"ptr:backcolor="2"ptr:big="false"ptr:home="2"ptr:text="火车票"ptr:textSize="24sp" /></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:layout_marginRight="8dp"android:layout_marginBottom="8dp"android:orientation="vertical" ><com.chm.test.view.HomeButtonandroid:layout_width="200dp"android:layout_height="200dp"ptr:backcolor="3"ptr:big="false"ptr:home="3"ptr:text="团购"ptr:textSize="24sp" /><com.chm.test.view.HomeButtonandroid:layout_width="200dp"android:layout_height="200dp"android:layout_marginTop="8dp"android:background="#aaa"ptr:backcolor="4"ptr:big="true"ptr:home="4"ptr:text="机票"ptr:textSize="24sp" /><com.chm.test.view.HomeButtonandroid:layout_width="200dp"android:layout_height="200dp"android:layout_marginTop="8dp"ptr:backcolor="5"ptr:big="false"ptr:home="5"ptr:text="送机"ptr:textSize="24sp" /><com.chm.test.view.HomeButtonandroid:layout_width="200dp"android:layout_height="200dp"ptr:backcolor="6"android:layout_marginTop="8dp"ptr:big="false"ptr:home="6"ptr:text="景点门户"ptr:textSize="24sp" /></LinearLayout></LinearLayout></LinearLayout></ScrollView>

android 仿去哪儿首页效果相关推荐

  1. Android 仿今日头条首页标题栏效果

    今天带来的是仿今日头条首页的联动滑动效果,废话不多说,先上效果图: 思路: 做这个我们需要实现的效果有 1.滑动内容区域,标题栏会有变化来显示当前所处的位置. 2.点击标题栏,内容区域也会随着滑动并跳 ...

  2. android仿微信的activity平滑水平切换动画,Android实现简单底部导航栏 Android仿微信滑动切换效果...

    Android实现简单底部导航栏 Android仿微信滑动切换效果 发布时间:2020-10-09 19:48:00 来源:脚本之家 阅读:96 作者:丶白泽 Android仿微信滑动切换最终实现效果 ...

  3. Android仿淘宝首页UI(附代源代码及示例图片)

    Android仿淘宝首页UI(附代源代码及示例图片) 可以收获 运行出来的效果 部分代码 源代码 可以收获 更改Layout中的文字和drawble中的图片即可生成适应于不同情景的APP,帮助开发者完 ...

  4. Android实现支付宝AR功能,Android RecyclerView 实现支付宝首页效果

    Android RecyclerView 实现支付宝首页效果 [TOC] 虽然我本人不喜欢支付宝的,但是这个网格本身其实还是不错的,项目更新中更改了一个布局为网格模式,类似支付宝.(估计是产品抄袭的= ...

  5. 基于android的高仿抖音,Android仿抖音列表效果

    本文实例为大家分享了Android仿抖音列表效果的具体代码,供大家参考,具体内容如下 当下抖音非常火热,是不是也很心动做一个类似的app吗? 那我们就用RecyclerView实现这个功能吧,关于内存 ...

  6. Android仿微信头像放大效果

    android仿微信头像放大效果,使用Dialog+Gallery 实现 1.  dialog显示时的动画style,动画可以自己根据喜好自己设置,此处动画xml省略 <style name=& ...

  7. android仿ppt,android 仿ppt进入动画效果合集

    EnterAnimation android 仿ppt进入动画效果合集, 百叶窗效果,擦除效果,盒状效果,阶梯效果,菱形效果,轮子效果,劈裂效果,棋盘效果, 切入效果,扇形展开效果,十字扩展效果,随机 ...

  8. android仿抖音礼物列表实现,Android仿抖音列表效果

    本文实例为大家分享了Android仿抖音列表效果的具体代码,供大家参考,具体内容如下 当下抖音非常火热,是不是也很心动做一个类似的app吗? 那我们就用RecyclerView实现这个功能吧,关于内存 ...

  9. android仿抖音关注列表,Android仿抖音列表效果

    本文实例为大家分享了Android仿抖音列表效果的具体代码,供大家参考,具体内容如下 当下抖音非常火热,是不是也很心动做一个类似的app吗? 那我们就用RecyclerView实现这个功能吧,关于内存 ...

最新文章

  1. Linux文件系统2---VFS的四个主要对象
  2. html5 progress css,CSS content: attr() on HTML5 progress doesn't work
  3. 框架:spring、springmvc、springboot
  4. Facebook最伟大的技术成就有哪些
  5. CISSP的成长之路(二十一):用户持有凭证
  6. js方式调用php_举例说明JS调用PHP和PHP调用JS的方法
  7. K8S精华问答 | Kubernetes用的是Docker的容器?
  8. Verizon的SDN策略:不鸣则已,一鸣惊人?
  9. h5球的立体效果_使用HTML5 Canvas 2D直角坐标系实现三维球体效果
  10. basys3利用microblaze连接Pmod ad2
  11. Python线程池简介
  12. PS批量处理_将图片批量转为jpg
  13. 国内液压与气动标准大全
  14. PyTorch以及VGG模型
  15. 怎样在微信中直接下载秒借类金融贷款APP,避免下载链接域名被微信屏蔽封杀的处理方式
  16. App 抓包利器:Charles
  17. 4G模块中RSRP RSRQ RSSI SINR等信号值的含义和区别
  18. 分数化小数计算机在线,循环小数化分数计算器
  19. 如何设计手机端banner图【电商小白】
  20. JAVA与C、C++比较

热门文章

  1. 关系抽取远程监督PCNN:Distant Supervision for Relation Extraction via Piecewise Convolutional Neural Networks
  2. 论文阅读“Graph Clustering via Variational Graph Embedding”(PR2022)
  3. COMSOL电化学基于燃料电池、纽扣电池、锂电池等多种案例
  4. py2exe qt界面风格变成了win98解决方案
  5. QPainter::begin: Painter already active问题解决方案
  6. 《图论及其应用》学习笔记(Euler图与Hamilton图)
  7. Java+UEditor
  8. python动态表情包_Python从eif中导出qq表情的gif图片
  9. 数字图像中关于添加噪声及噪声处理
  10. 17个设计灵感创意网站