我正在将一个 iOS 应用程序复制到 Android 中。该应用程序有一个带有信用卡动画的“钱包”屏幕,请参阅下面的 iOS 应用程序视频。如何在 Android 中实现类似的功能?
这是 iOS 钱包的视频 -> Wallet iOS demo
我需要复制这些函数:
这是 iOS 中用于使其工作的库 GLStackedViewController .
最佳答案
我最终从头开始制作它,不需要任何库并使用常规的 ListView。
在包含所有卡片的 cardHolder fragment 中,当单击第一个项目 (0) 时,卡片弹跳然后转到详细信息 fragment ,当单击不是第一个的其他项目时,只需更改 ListView 顺序并更新适配器,这里缺少的一件事是点击之间的卡片动画,仍然是一个 WIP。
// Click event for single list row
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
Log.d(TAG, "Position: " + position);
final FragmentAccount fragment = new FragmentAccount();
// Fisrt card
if (position == 0) {
// Animated bounce effect
Animation anim = AnimationUtils.loadAnimation(view.getContext(), R.anim.expand_in);
view.startAnimation(anim);
// delay click event (anim duration) and go to new fragment
new Handler().postDelayed(new Runnable() {
public void run() {
if (listBalance.get(position).get(TAG_ACCOUNT_BANKACCOUNTS_ID) != null) {
((GlobalVars) getActivity().getApplication()).setIdBankAccount(Integer.valueOf(listBalance.get(position).get(TAG_ACCOUNT_BANKACCOUNTS_ID)));
((GlobalVars) getActivity().getApplication()).setIdGiftCard(0);
((GlobalVars) getActivity().getApplication()).setCardBalance("");
} else if (listBalance.get(position).get(TAG_ACCOUNT_GIFTCARDS_ID) != null) {
((GlobalVars) getActivity().getApplication()).setIdBankAccount(0);
((GlobalVars) getActivity().getApplication()).setIdGiftCard(Integer.valueOf(listBalance.get(position).get(TAG_ACCOUNT_GIFTCARDS_ID)));
((GlobalVars) getActivity().getApplication()).setCardBalance(listBalance.get(position).get(TAG_ACCOUNT_GIFTCARDS_BALANCE));
} else {
((GlobalVars) getActivity().getApplication()).setIdBankAccount(0);
((GlobalVars) getActivity().getApplication()).setIdGiftCard(0);
((GlobalVars) getActivity().getApplication()).setCardBalance(listBalance.get(position).get(TAG_ACCOUNT_X111_BALANCE));
}
((BaseContainerFragment) getParentFragment()).replaceFragment(fragment, true);
}
}, anim.getDuration());
}
// Item is not the first, so trade places with first one
else {
HashMap<String, String> tmp = listBalance.get(0);
Log.d(TAG, tmp.toString());
listBalance.set(0, listBalance.get(position));
listBalance.set(position, tmp);
adapter.notifyDataSetChanged();
updateAdapter();
}
}
});
弹跳动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="50"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.1"
android:toYScale="1.1" />
<scale
android:duration="50"
android:fromXScale="0.9"
android:fromYScale="0.9"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="50"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
适配器
public View getView(final int position, View convertView, ViewGroup parent) {
vi = convertView;
if (layout == "account") {
if (convertView == null) {
vi = inflater.inflate(R.layout.activity_account_list_item, null);
}
TextView transaction_name = (TextView) vi.findViewById(R.id.account_name);
TextView transaction_address = (TextView) vi.findViewById(R.id.account_address);
TextView transaction_date = (TextView) vi.findViewById(R.id.account_date);
ImageView transaction_icon = (ImageView) vi.findViewById(R.id.account_image);
HashMap<String, String> transactions = new HashMap<String, String>();
transactions = data.get(position);
// Setting all values in listview
transaction_name.setText(transactions.get(FragmentCardBalance.TAG_ACCOUNT_TRANSACTIONS_NAME));
transaction_address.setText(transactions.get(FragmentCardBalance.TAG_ACCOUNT_TRANSACTIONS_ADDRESS));
transaction_date.setText(transactions.get(FragmentCardBalance.TAG_ACCOUNT_TRANSACTIONS_DATE));
imageLoader.DisplayImage(transactions.get(FragmentCardBalance.TAG_ACCOUNT_TRANSACTIONS_ICON), transaction_icon);
}
else if (layout == "balance") {
String[] color = { "56a77a","568fa7" ,"f8d243", "8fb63c", "114783", "e1ac47", "58ACFA", "819FF7", "5858FA",
"AC58FA", "FE9A2E", "FA5858", "FA5882"};
//Log.d("COLOR", "Color: " + color[position] + " | Position: " +position);
if (convertView == null && position == 0) {
vi = inflater.inflate(R.layout.activity_cardholder_list_item_first, null);
TextView saldo = (TextView) vi.findViewById(R.id.tvSaldo);
TextView balance_idBankAccount = (TextView) vi.findViewById(R.id.idBankAccount);
TextView balance_idGiftCard = (TextView) vi.findViewById(R.id.idGiftCard);
TextView balance_amount = (TextView) vi.findViewById(R.id.tvAmount);
TextView balance_cardNumber = (TextView) vi.findViewById(R.id.tvCardNumber);
TextView balance_expDate = (TextView) vi.findViewById(R.id.tvExpDate);
ImageView balance_foto = (ImageView) vi.findViewById(R.id.ivLogo);
LinearLayout background = (LinearLayout) vi.findViewById(R.id.background);
GradientDrawable bgShape = (GradientDrawable)background.getBackground();
HashMap<String, String> balance = new HashMap<String, String>();
balance = data.get(position);
// Setting all values in listview
balance_idBankAccount.setText(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_ID));
balance_idGiftCard.setText(balance.get(FragmentCardHolder.TAG_ACCOUNT_GIFTCARDS_ID));
if(balance.get(FragmentCardHolder.TAG_ACCOUNT_X111_BALANCE) == null){
if(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_TYPE).equals("1")){
balance_amount.setText("CREDITO");
} else {
balance_amount.setText("DEBITO");
}
String card = balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_CARDNUMBER);
card = "**** **** **** " + card.substring(card.length() - 4, card.length());
balance_cardNumber.setText(card);
if (saldo != null) {
saldo.setText("");
}
} else {
balance_amount.setText("$ " + balance.get(FragmentCardHolder.TAG_ACCOUNT_X111_BALANCE));
balance_expDate.setText("");
balance_cardNumber.setText("");
}
imageLoader.DisplayImage(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_FOTO), balance_foto);
bgShape.setColor(Color.GREEN);
if(color != null){
bgShape.setColor(Integer.parseInt(color[position], 16) + 0xFF000000);
}
}
// set layout for the next items
else if (convertView == null && position != 0) {
vi = inflater.inflate(R.layout.activity_cardholder_list_item, null);
TextView saldo = (TextView) vi.findViewById(R.id.tvSaldo);
TextView balance_idBankAccount = (TextView) vi.findViewById(R.id.idBankAccount);
TextView balance_idGiftCard = (TextView) vi.findViewById(R.id.idGiftCard);
TextView balance_amount = (TextView) vi.findViewById(R.id.tvAmount);
ImageView balance_foto = (ImageView) vi.findViewById(R.id.ivLogo);
LinearLayout background = (LinearLayout) vi.findViewById(R.id.background);
GradientDrawable bgShape = (GradientDrawable)background.getBackground();
HashMap<String, String> balance = new HashMap<String, String>();
balance = data.get(position);
// Setting all values in listview
balance_idBankAccount.setText(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_ID));
balance_idGiftCard.setText(balance.get(FragmentCardHolder.TAG_ACCOUNT_GIFTCARDS_ID));
if(balance.get(FragmentCardHolder.TAG_ACCOUNT_X111_BALANCE) == null){
if(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_TYPE).equals("1")){
balance_amount.setText("CREDITO");
} else {
balance_amount.setText("DEBITO");
}
saldo.setText("");
} else {
balance_amount.setText("$ " + balance.get(FragmentCardHolder.TAG_ACCOUNT_X111_BALANCE));
}
imageLoader.DisplayImage(balance.get(FragmentCardHolder.TAG_ACCOUNT_BANKACCOUNTS_FOTO), balance_foto);
if(color[position] != null){
bgShape.setColor(Integer.parseInt(color[position], 16) + 0xFF000000);
}
}
}
}
关于android - 将 iOS Controller 复制到 Android 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33426118/
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我想编写一个ruby脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"
之前有人问过这个问题,我发现了以下clip关于如何一次设置一个类对象的所有属性,但由于批量分配保护,这在Rails中是不可能的。(例如,您不能Object.attributes={})有没有一种很好的方法可以将一个类的属性合并到另一个类中?object1.attributes=object2.attributes.inject({}){|h,(k,v)|h[k]=vifObjectModel.column_names.include?(k);h}谢谢。 最佳答案 利用assign_attributes使用:without_prote
(跟进我之前的问题,Ruby:howcanIcopyavariablewithoutpointingtothesameobject?)我正在编写一个简单的Ruby程序来在.svg文件中进行一些替换。第一步是从文件中提取信息并将其放入数组中。为了避免每次调用此函数时都从磁盘读取文件,我尝试使用memoize设计模式-在第一次调用后的每次调用中都使用缓存结果。为此,我使用了一个在函数之前定义的全局变量。但是,即使我在返回局部变量之前将该变量.dup为局部变量,调用该变量的函数仍在修改全局变量。这是我的实际代码:#memoizetokeepfromhavingtoreadoriginalfi
我有一台服务器,其中只有xls日志文件。每个文件为5-15Mb,并且在文件随时添加的意义上是动态的。现在我需要一种使用Ruby执行以下过程的方法。通过将文件名从一台只有日志文件的服务器发送到另一台服务器来复制文件。我需要将服务器密码作为参数传递。一切都在后台发生,由Ruby脚本触发。 最佳答案 查看Net::SCP和Net::SSHgem。第一个让您使用安全副本检索文件,第二个让您轻松找到可用于检索的文件的名称。在Net::SSH中,ssh.exec!将成为您的friend。来自Net::SCP文档:Net::SCPimplemen
Rails有一个.blank?如果对象为空,将返回true的方法?还是零?可以找到实际代码here.当我尝试在1.9.2上复制它时:classObjectdefblank?respond_to?(:empty?)?empty?:!selfendend调用“.blank”?返回true但调用"".blank?根据railsdocumentation返回false对于.blank,空白字符串应该eval为true?在查看我最初编写的代码之前:classObjectdefblank?!!self.empty?||!!self.nil?endend结果相同。我错过了什么?
当我尝试预编译我的Assets时,出现以下错误。这是具有完整输出的跟踪:RAILS_ENV=productionbundleexecrakeassets:precompile--trace**Invokeassets:precompile(first_time)**Invokeassets:environment(first_time)**Executeassets:environment**Invokeenvironment(first_time)**Executeenvironmentrakeaborted!TypeError:can'tdupNilClass/var/lib/ge
我遇到一个奇怪的问题,我正在使用的Rails引擎中的某些模型在对象空间中被复制。(rdb:1)ObjectSpace.each_object(::Class).each{|klass|putsklass.to_s+":"+klass.object_id.to_sifklass.to_s.eql?("DynamicFieldsets::Field")}DynamicFieldsets::Field:66866100DynamicFieldsets::Field:718363802479发生这种情况时,我不能使用is_a?或相等性检查以测试对象是否是Field类的实例。这个问题只发生在开发
我的目标是将一组由模式指定的文件复制到目标目录。源目录中的文件可以有子目录。我试过:cp_r(Dir.glob('**/*.html'),@target_dir):和cp_r(FileList['**/*.html'],@target_dir):但都不起作用。它只在我做类似的事情时有效:cp_r(Dir['.'],@target_dir):但我只需要复制*.html文件而不是其他任何文件。我需要什么cp--parents命令确实对使用现有的Ruby/Rake方法有什么建议吗?更新看起来用Ant更容易做的事情,用Ruby/Rake堆栈是不可能的-可能我需要研究其他东西。我不想编写自定义代
也许我今天盯着屏幕看的时间太长了,但我认为应该是非常基本的东西却难倒了我。我正在尝试制作一个变量的“副本”,这样我就可以在不修改原始变量的情况下对其进行操作。#originalvarissetfoo=["a","b","c"]#iwantacopyoftheoriginalvarsoidontmodifytheoriginalbar=foo#modifythecopiedvarbar.delete("b")#outputthevaluesputsbar#outputs:["a","c"]-thisisrightputsfoo#outputs:["a","c"]-whyisthisals