制作简易的3D相册

article/2025/10/12 12:47:26

  今天介绍一下3D相册,用到了开源的FeatureCoverFlow控件,之前的几个作品用的也全都是开源的控件,为什么要用开源的控件呢,因为...他稳定啊!

1.准备

  仍然是,去掉标题栏,然后导库:

implementation 'com.github.moondroid.coverflow:library:1.0'  

  导完库之后就会发现一个错误
5d1cbaa83f5a717574.png

  看见没,报错了,minSDK版本最小是15,我的才14
5d1cbacd8643181142.png

  不过没关系,很简单,直接把14改成15就好了
  在写程序之前,我们先导入我们所需要的相册中的图片
5d1cbad5f0c0a89673.png

  emmmmm,导入到drawable的hdpi目录下(高分辨率),不要搞错了,不懂的话参考我的这篇文章,虽然我什么也没写(此处有坏笑)

5d1cbade1630224962.png

  看,导入成功了!

2.布局文件

(1).主布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:coverflow="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/darker_gray"tools:context=".MainActivity"><it.moondroid.coverflow.components.ui.containers.FeatureCoverFlowandroid:id="@+id/coverflow"android:layout_width="match_parent"android:layout_height="match_parent"coverflow:coverHeight="180dp"coverflow:coverWidth="120dp"coverflow:maxScaleFactor="1.5"coverflow:reflectionGap="0dp"coverflow:rotationThreshold="0.5"coverflow:scalingThreshold="0.5"coverflow:spacing="0.6" /><TextSwitcherandroid:id="@+id/title"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="0dp"coverflow:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>

  这里采用的依旧是ConstraintLayout布局,里面放置了一个FeatureCoverFlow控件和一个TextSwitcher控件,其中FeatureCoverFlow控件用来显示相册,TextSwitcher用来显示图片的标题

(2) item_album.xml

  由于相册界面使用的FeatureCoverFlow控件展示的是图片组合,因此我们要创建一个该组合的Item,Item界面主要显示一张图片,而不是一组图片。
  在res/layout目录下新建item_album.xml文件,在文件中放置一个ImageView控件,用来显示当前正在查看的图片。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="120dp"android:layout_height="180dp"android:clickable="true"android:focusable="true"android:foreground="@drawable/album_selector"><ImageViewandroid:id="@+id/img"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="centerCrop"/>
</android.support.constraint.ConstraintLayout>

(3) album_selector.xml

  创建一个背景选择器,使得在相册界面,每次点击图片时,图片背景有明显变化。在drawable目录下新建Drawable resourse file,名字改为album_selector,当图片被按下时,显示图片背景为灰色(#96000000)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><color android:color="#96000000" />
</item>
<item><color android:color="@android:color/transparent" />
</item>
</selector>

(4) item_title.xml

  还记得吗?由于我们在主界面放置了TextSwitcher控件,而该控件在实现ViewFactory接口中的makeView()方法时必须返回一个TextView控件,所以需要在res/layout目录下新建item_title.xml文件,文件中放置一个需要返回的TextView控件:

<?xml version="1.0" encoding="utf-8"?>
<TextView 
xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:textAppearance="?android:textAppearanceLargeInverse"android:textColor="@android:color/white" />

(5).标题出入动画效果

  为了更好的用户体验,决定在标题上做一些文章,使得在显示图片标题是,信息会从下向上缓缓进入界面,当标题消失时,信息会从上向下缓缓离开界面。在res文件夹中创建一个anim文件夹,然后分别创建slide_in_top.xml文件和slide_out_bottom.xml文件,以显示动画效果

1. slide_in_top.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translateandroid:duration="@android:integer/config_mediumAnimTime"android:fromYDelta="100%p"android:toYDelta="0" />
<alphaandroid:duration="@android:integer/config_mediumAnimTime"android:fromAlpha="0.0"android:toAlpha="1.0" />
</set>

2. slide_out_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translateandroid:duration="@android:integer/config_mediumAnimTime"android:fromYDelta="0"android:toYDelta="100%p" />
<alphaandroid:duration="@android:integer/config_mediumAnimTime"android:fromAlpha="1.0"android:toAlpha="0.0" /></set>

(6).标题

  由于我们一共导入了5张图片,所以应该为他们赋予5个名字,在res/String文件夹下面的strings.xml中添加五个标题

<resources>
<string name="app_name">3D</string>
<string name="title1">GG</string>
<string name="title2">Spring Scenery</string>
<string name="title3">Summer Scenery</string>
<string name="title4">Autumn Scenery</string>
<string name="title5">Winter Scenery</string>
</resources>

3.界面逻辑

(1)AlbumBean.java

  由于相册界面主要显示一组图片,每张图片都有自己的图片ID和标题ID的属性,所以为了方便起见,我们新建一个AlbumBean类来存放图片的这些属性

package com.project.software.a3d;public class AlbumBean {
public int imgResId;    //图片Id
public int titleResId; //图片标题Id
public AlbumBean(int imgResId, int titleResId) {this.imgResId = imgResId;this.titleResId = titleResId;
}
}

(2)适配器

  由于相册界面显示的一组图片是通过FeatureCoverFlow控件实现的,因此需要创建一个数据适配器AlbumAdapter对该控件进行数据适配

package com.project.software.a3d;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import java.util.ArrayList;
public class AlbumAdapter extends BaseAdapter {
private ArrayList<AlbumBean> dataList = new ArrayList<>();
private Context mContext;
public AlbumAdapter(Context context) {mContext = context;
}
public void setData(ArrayList<AlbumBean> dataList) {this.dataList = dataList;
}
@Override
public int getCount() {return dataList.size();
}
@Override
public Object getItem(int position) {return dataList.get(position);
}
@Override
public long getItemId(int position) {return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {if (convertView == null) {LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);convertView = inflater.inflate(R.layout.item_album, null);ViewHolder viewHolder = new ViewHolder();viewHolder.iv_img = (ImageView) convertView.findViewById(R.id.img);convertView.setTag(viewHolder);}ViewHolder holder = (ViewHolder) convertView.getTag();holder.iv_img.setImageResource(dataList.get(position).imgResId);return convertView;
}
public class ViewHolder {public ImageView iv_img;
}
}

  在这个适配器中,1.创建一个AlbumAdapter类继承自BaseAdapter类,并重写getCount()、getItem()、getItemId()、getView()方法,并在getView()方法中通过inflate()方法加载相册界面的Item布局文件item_album.xml,然后将图片设置到界面控件上。2.创建一个ViewHolder类的Item界面上的图片控件对应的字段

(3)主逻辑

  主界面显示一组图片,并可以通过左右滑动在进行切换,同时图片下方会显示该图片的标题,点击任意一张图片会显示该图片的标题信息:

package com.project.software.a3d;import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.TextSwitcher;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;
import java.util.ArrayList;import it.moondroid.coverflow.components.ui.containers.FeatureCoverFlow;public class MainActivity extends AppCompatActivity {
private FeatureCoverFlow coverFlow;
private AlbumAdapter adapter;
private ArrayList<AlbumBean> dataList;
private TextSwitcher mTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initData();initView();
}
/*** 初始化界面控件*/
private void initView() {mTitle = (TextSwitcher) findViewById(R.id.title);mTitle.setFactory(new ViewSwitcher.ViewFactory() {@Overridepublic View makeView() {LayoutInflater inflater = LayoutInflater.from(MainActivity.this);TextView title = (TextView) inflater.inflate(R.layout.item_title, null);return title;}});Animation in = AnimationUtils.loadAnimation(this, R.anim.slide_in_top);Animation out = AnimationUtils.loadAnimation(this, R.anim.slide_out_bottom);mTitle.setInAnimation(in);mTitle.setOutAnimation(out);coverFlow = (FeatureCoverFlow) findViewById(R.id.coverflow);adapter = new AlbumAdapter(this);adapter.setData(dataList);coverFlow.setAdapter(adapter);coverFlow.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {if (position < dataList.size()) {Toast.makeText(MainActivity.this,getResources().getString(dataList.get(position).titleResId),Toast.LENGTH_SHORT).show();}}});coverFlow.setOnScrollPositionListener(new FeatureCoverFlow.OnScrollPositionListener() {@Overridepublic void onScrolledToPosition(int position) {mTitle.setText(getResources().getString(dataList.get(position).titleResId));}@Overridepublic void onScrolling() {mTitle.setText("");}});
}
/*** 初始化界面数据*/
private void initData() {dataList = new ArrayList<>();dataList.add(new AlbumBean(R.drawable.i1, R.string.title1));dataList.add(new AlbumBean(R.drawable.i2, R.string.title2));dataList.add(new AlbumBean(R.drawable.i3, R.string.title3));dataList.add(new AlbumBean(R.drawable.i4, R.string.title4));dataList.add(new AlbumBean(R.drawable.i5, R.string.title5));
}
protected long exitTime;//记录第一次点击时的时间
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK&& event.getAction() == KeyEvent.ACTION_DOWN) {if ((System.currentTimeMillis() - exitTime) > 2000) {Toast.makeText(MainActivity.this, "再按一次退出3D相册",Toast.LENGTH_SHORT).show();exitTime = System.currentTimeMillis();} else {MainActivity.this.finish();System.exit(0);}return true;}return super.onKeyDown(keyCode, event);
}
}

  在主逻辑中,1.创建一个initData()方法,在该方法中创建界面所需要的图片数据,并在该方法中重写onKeyDown()方法,判断两次点击'后退'键的时间间隔是否小于2s,如果小于2s则退出该程序,如果大于2秒,则提示“再按一次退出3D相册”。2.创建一个initView()方法 ,在该方法中获取相册界面的控件并设置相关的点击事件与滑动时间。

  最后仍然是老规矩,放图:

5d1cbaf0765be65489.gif

Over

转载于:https://www.cnblogs.com/zqm-sau/p/9158794.html


http://chatgpt.dhexx.cn/article/o5bGYgpA.shtml

相关文章

HTML5、css3、js实现3D相册

目录 想法 实现 一、基础知识 1.3D转换 transform-style: preserve-3d; ①简述 ②使用 ③3D转换方法 2.onmouseover 事件 ①解释 ②具体语法 3.onmouseout事件 ①解释 ②具体语法 **本例通过在div的class中设置相同的类名&#xff0c;然后在js方法中通过document…

前端CSS3实现3D相册小案例

前端CSS3实现3D相册小案例 HTML代码部分&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>3D相册</title> <link type"text/css" href"css/style.css&qu…

制作一个简单3D相册

- 用到的点&#xff1a; 旋转 2D 旋转 transform: rotate(值deg) deg 角度的单位 3D 旋转 transform:rotateX rotateY roteteZ 如果让一个块实现3D效果&#xff0c;必须做两件事&#xff1a; 1、在要实现3D效果的块上 加transform-style:preserve-3D (声明) 2、在要实现3D效…

html结合css实现浏览器展示3D相册

最近写了一个在浏览器展示3D相册效果&#xff0c;通过html文件结合css实现。 1.html详细代码如下&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>3D相册</title> <script src"../js/jquer…

python3d相册源代码_js和CSS3炫酷3D相册展示

js和CSS3炫酷3D相册展示 *{margin:0;padding:0;} body{background:url(img/bg.jpg);width:100%;height:100%;overflow:hidden;}; h1{width:277;height:76px;margin:30px auto 0;} .xc-3D{width:100%;height:300px;background:#fff;margin-top:100px;position:relative;transfor…

three.js 制作3D相册

效果图&#xff1a; 由于博客限制了图片大小&#xff0c;动画质量不太好&#xff0c; 在线效果&#xff1a; https://static-mp-df787464-d77c-4180-83c3-6e7add40073e.next.bspapp.com/ 参考了three.js 官方代码 <!-- 源码下载地址 https://pan.baidu.com/s/1AVB71Aj…

3d相册

页面脚本 我的图片是是本地的&#xff0c;大家可以放上自己喜爱的图片 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>3d相册</title></head><style>#box1 {/* 宽 */width: 300px;/* 高 */height: …

HTML实现3D相册

今天&#xff0c;我给大家分享一个3D相册的代码 废话不说先上效果图&#xff1a; 先新建两个文件夹&#xff0c;一个叫css&#xff0c;另一个叫img&#xff0c;如下图&#xff1a; 先新建一个文本文档&#xff0c;输入下面的代码&#xff1a; <!DOCTYPE html> <html…

教你零基础制作3D旋转相册(送给那个她~)

3D立体相册&#xff1f;   是的&#xff0c;相信大家或多或少的会在一些地方看到某些程序员用代码给自己女朋友写3D立体相册&#xff0c;那么你会不会也想自己手动敲出那些炫酷的代码呢&#xff1f;   那你是找对地方了。废话不多说&#xff0c;今天为大家分享利用html实现…

【3D相册】零基础完成3D相册并配上背景音乐

文章目录 一、前言二、准备工作1、新建文件夹2、准备素材对于图片的处理对于音乐的处理 三、代码工作1、python处理6张图片1.1代码运行1.2 放入背景图片 2、写html文件2.1 更换音乐素材 3、运行main.html 四、推荐阅读 一、前言 帮助好哥们整的一个小相册&#xff0c;给他写个…

斐波那契数列求和公式

斐波那契数列指的是这样一个数列&#xff1a;1、1、2、3、5、8、13、21、……    这个数列从第三项开始&#xff0c;每一项都等于前两项之和。它的通项公式为:(见下图)&#xff08;又叫“比内公式”&#xff0c;是用无理数表示有理数的一个范例。&#xff09; 斐波那契数列求…

斐波那契数列之python(5种方法)

斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列、因数学家列昂纳多斐波那契&#xff08;Leonardoda Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为“兔子数列”&#xff0c;指的是这样一个数列&#xff1a;1、1、2、…

斐波那契数列(C/C++)

目录 背景介绍 解法1&#xff1a;非数组非递归 解法2&#xff1a;数组非递归 解法3&#xff1a;非数组递归 解法4&#xff1a;数组递归 背景介绍 斐波那契数列&#xff0c;又称黄金分割数列&#xff0c;指的是这样一个数列&#xff1a;0、1、1、2、3、5、8、13、21、34、…

关于斐波那契数列通项公式证明以及推广

在我们中学的时候老师都会举一个著名的兔子繁殖的例子&#xff1a;一般而言&#xff0c;兔子在出生两个月后&#xff0c;就有繁殖能力&#xff0c;一对兔子每个月能生出一对小兔子来。如果所有兔子都不死&#xff0c;那么一年以后可以繁殖多少对兔子&#xff1f;而这个问题就是…

斐波那契数列的四种解法

题目描述 斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列&#xff0c;因数学家莱昂纳多斐波那契&#xff08;Leonardo Fibonacci&#xff09;以兔子繁殖为例子而引入&#xff0c;故又称为“兔子数列”&#xff0c;指的是这样一个数列&a…

斐波那契数列通项公式的求法

以下两种方法其实是一样的 1、方法一 其实所有人都知道T(n) T(n-1) T(n-2), T(1) T(2)1,T(n)也是一个斐波那契数列&#xff0c;求解时间复杂度的本质也就是求数列通项&#xff0c;结果MB的一个通项就把我难住了&#xff0c;只好回来google一下&#xff0c;把高中数学用的求…

【算法】斐波那契数列通项公式

特征方程和通项公式 如果数列 a n a_n an​的递推公式&#xff1a; a n c 1 a n − 1 c 2 a n − 2 a_nc_1a_{n-1}c_2a_{n-2} an​c1​an−1​c2​an−2​------(1) 根据待定系数法&#xff0c;假设 a n − x a n − 1 y ( a n − 1 − x a n − 2 ) a_n-xa_{n-1}y(a_{n-1…

斐波那契数列通项公式的推导证明----举一反三

斐波那契数列通项公式的推导证明----举一反三 1-前言2-斐波那契2-1-什么是斐波那契2-2-通项公式的证明2-3-举一反三 1-前言 2021年5月20号的那天&#xff0c;有对象的都忙着约会秀恩爱&#xff0c;而我这样的单身狗&#xff0c;只能自己学习沉淀自己&#xff0c;为梦想而奔波&a…

七种方式求斐波那契(Fibonacci)数列通项

一&#xff1a;递归实现   使用公式f[n]f[n-1]f[n-2]&#xff0c;依次递归计算&#xff0c;递归结束条件是f[1]1&#xff0c;f[2]1。 二&#xff1a;数组实现   空间复杂度和时间复杂度都是0(n)&#xff0c;效率一般&#xff0c;比递归来得快。 三&#xff1a;vector<in…