import org.json.JSONArray
import java.io.*
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.StandardOpenOption
fun main() {
// CLEAR TEXT FILE WITHOUT DELETING IT
val pathObject = Paths.get("C:\\Projects\\Project\\Localizable.strings")
Files.newBufferedWriter(pathObject , StandardOpenOption.TRUNCATE_EXISTING);
Files.newInputStream(pathObject , StandardOpenOption.TRUNCATE_EXISTING);
// code
var count = 0
var match = 0
var not = 0
var isMatched = false
val englishLangData = readJson1()
val otherLangData = readJson3()
val list = englishLangData.split(";")
// Main Local.strings
for (item in list) {
isMatched = false
try {
val key1 = item.trim().split("=")[1].replace("\"", "").toString().trim()
val value1 = item.trim().split("=")[1].replace("\"", "").toString().trim()
// CODE- language to be replaced
val jsonArr = JSONArray(otherLangData)
for (item2 in jsonArr) {
val s = item2.toString()
val j1 = JSONArray(s)
val s1 = j1[0].toString().trim()
val s2 = j1[1].toString().trim()
if (s1.equals(value1, true)) {
val s = "\""+key1+"\" = \""+s2+"\";"
val s2 = "\n" + s
val fileWriter = FileWriter("C:\\Projects\\Project\\Localizable.strings", true)
fileWriter.write(s2)
fileWriter.close()
isMatched = true
match = match + 1
break
}
}
if (isMatched == false){
val s = "\""+key1+"\" = \""+value1+"\";"
val s2 = "\n" + s
val fileWriter = FileWriter("C:\\Projects\\Project\\Localizable.strings", true)
fileWriter.write(s2)
fileWriter.close()
}
} catch (exc: Exception) {}
count = count + 1
if (count == 460){
break
}
}
println("matched size : " + match)
println("not matched size : " + not)
}
fun readJson1(): String {
val writer: Writer = StringWriter()
val buffer = CharArray(1024)
try {
val file1 = File("C:\\Projects\\Project\\EicherLiveStaticStrings_Malyalam.xlsx")
val file = File("C:\\Projects\\Project\\Localizable_main_formatted.strings")
val reader: Reader = BufferedReader(FileReader(file))
var n1: Int = 0
while (reader.read(buffer).also({ n1 = it }) != -1) {
writer.write(buffer, 0, n1)
}
} finally {
// fil.close()
}
val jsonString: String = writer.toString()
return jsonString
}
fun readJson3(): String {
val writer: Writer = StringWriter()
val buffer = CharArray(1024)
try {
val file = File("C:\\Projects\\Project\\formatted_malayalam_arr_json.json")
val reader: Reader = BufferedReader(FileReader(file))
var n1: Int = 0
while (reader.read(buffer).also({ n1 = it }) != -1) {
writer.write(buffer, 0, n1)
}
} finally {
// fil.close()
}
val jsonString: String = writer.toString()
return jsonString
}
Android Program
Tuesday 7 December 2021
RepLace Multi-Language Programmatically
Wednesday 15 May 2019
MVVM
Library
def lifecycle_version = "1.1.1" // ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable
name="viewModel"
type="com.app.testapp.UserProfileViewModel" /> </data> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimary"
android:textSize="30sp"
android:hint="hint" /> <Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="@{()->viewModel.buttonClick()}"
android:layout_marginTop="36dp" /> </LinearLayout> </LinearLayout> </layout>
MainActivity.java
package com.app.testapp; import android.arch.lifecycle.Observer; import android.arch.lifecycle.ViewModelProviders; import android.databinding.DataBindingUtil; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.app.testapp.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity { UserProfileViewModel userProfileViewModel; TextView textView; // Button button2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.activity_main); userProfileViewModel = ViewModelProviders.of(MainActivity.this).get(UserProfileViewModel.class); ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setViewModel(userProfileViewModel); binding.setLifecycleOwner(this); setContentView(binding.getRoot()); textView = (TextView) findViewById(R.id.textView); // button2 = (Button)findViewById(R.id.button2); // String s = userProfileViewModel.user.name + "\n" + userProfileViewModel.user.company;// textView.setText(s); // button2.setOnClickListener(new View.OnClickListener() {// @Override// public void onClick(View v) {////// userProfileViewModel.getUser().setValue(new User("ABC", "XYZ"));//// userProfileViewModel.user.company = "XYZ";// }// }); // "abc".toLowerCase() userProfileViewModel.getUser().observe(this, new Observer<User>() { @Override public void onChanged(@Nullable User user) { textView.setText(user.name); } } ); } }
UserProfileViewModel.Java
package com.app.testapp; import android.arch.lifecycle.LiveData; import android.arch.lifecycle.MutableLiveData; import android.arch.lifecycle.ViewModel; import android.widget.Toast; public class UserProfileViewModel extends ViewModel { // User user = new User("No Name", "No Com"); private MutableLiveData<User> user = new MutableLiveData<User>(); LiveData<User> userLiveData; public MutableLiveData<User> getUser() { return user; } public void buttonClick(){ getUser().setValue(new User("ABC", "XYZ")); } }User.javapackage com.app.testapp; public class User { String name; String company; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public User(String name, String company) { this.name = name; this.company = company; } }
22
Friday 12 October 2018
Language Convertor
ActivityMain.xml
----------------------------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.2"
/>
<Button
android:id="@+id/actionEng"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="English"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.6"
/>
<Button
android:id="@+id/actionHi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hindi"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8"/>
</android.support.constraint.ConstraintLayout>
----------------------------------------------------------------------------------------
MainActivity.java
-----------------------------------------------------------------------------------------
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
TextView tvMessage;
Button actionEng, actionHi;
AppPrefs prefs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefs = new AppPrefs(this);
tvMessage = (TextView) findViewById(R.id.tvMessage);
actionEng = (Button)findViewById(R.id.actionEng);
actionHi = (Button)findViewById(R.id.actionHi);
actionEng.setOnClickListener(this);
actionHi.setOnClickListener(this);
tvMessage.setText(getResources().getString(R.string.txt_1));
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.actionEng:
{
setEnglish();
}
break;
case R.id.actionHi:
{
setHindi();
}
break;
}
}
private void setEnglish(){
String languageToLoad = "en"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
recreate();
}
private void setHindi(){
String languageToLoad = "hi"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
recreate();
}
}
Saturday 21 July 2018
Spannable TextView
XML
JAVA
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/tvMessage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" android:textSize="30sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
JAVA
import android.graphics.Color import android.graphics.Typeface import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.text.SpannableString import android.text.style.ForegroundColorSpan import android.text.style.RelativeSizeSpan import android.text.style.StyleSpan import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tvMessage.text = generateCenterSpannableText() } private fun generateCenterSpannableText(): SpannableString { val s = SpannableString("I just have one question about colors template. For the LineChart, it is possible to show different colors : one for each line, but is it possible to show different colors for the same line ? I would like to draw different colors for circles, lines and also for the background under the line when the 'filled' option is enabled. I see that I can redefine the Paint object for the circles and change their color, but I can't do the same for lines and filled background, am I wrong ?") s.setSpan(RelativeSizeSpan(1.7f), 0, 2, 0) s.setSpan(StyleSpan(Typeface.NORMAL), 2, s.length - 1, 0) s.setSpan(ForegroundColorSpan(Color.GRAY), 14, s.length - 15, 0) s.setSpan(RelativeSizeSpan(.8f), 14, s.length - 15, 0) s.setSpan(StyleSpan(Typeface.ITALIC), s.length - 14, s.length, 0) s.setSpan(ForegroundColorSpan(getHoloBlue()), s.length - 14, s.length, 0) return s } fun getHoloBlue(): Int { return Color.rgb(51, 181, 229) } }
Friday 18 May 2018
Networking Library : Retrofit
STEP-1: Library
compile('com.squareup.retrofit2:retrofit:2.1.0') {
exclude module: 'okhttp'
}
STEP-2: API Client
public class APIClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String url) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
// OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60,TimeUnit.SECONDS).addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder()
.baseUrl(url)//localhost
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
}
3. API Interface
@POST("api/email_verification.json")
Call<AddFolderResponse> emailVerification(@Body EmailVerificationRequest emailVerificationRequest);
@Multipart
@POST("api/set_profile_picture.json")
Call<AddFolderResponse> profileImageUpload(@Part MultipartBody.Part file, @Part("file[]") RequestBody id_proof, @Query("token") String token);
4. APP Call
public void callWebServiceForEmailVerification(){
String token = prefs.getString(CONSTANTS.LOGGED_TOKEN);
EmailVerificationRequest emailVerirequest = new EmailVerificationRequest();
emailVerirequest.token = token;
APIInterface apiInterface = APIClient.getClient(CONSTANTS.BASE_URL).create(APIInterface.class);
if(NetworkClass.getInstance().checkInternet(PaidSubscriberDashboardActivity.this) == true){
ProgressClass.getProgressInstance().showDialog(PaidSubscriberDashboardActivity.this);
Call<AddFolderResponse> call = apiInterface.emailVerification(emailVerirequest);
call.enqueue(new Callback<AddFolderResponse>() {
@Override
public void onResponse(Call<AddFolderResponse> call, Response<AddFolderResponse> response) {
ProgressClass.getProgressInstance().stopProgress();
try {
if (response.isSuccessful()) {
if (response.body().getMessage().getSuccess().equalsIgnoreCase("success")) {
showAlertMsg("Alert", "Verfication email sended. Check your mail and follow instruction");
// AlertDialogSingleClick.getInstance().showDialog(SubscriberDashboardActivity.this, "Email Alert", "Verfication email sended. Check your mail and follow instruction");
}
}
}catch (NullPointerException npe){
Log.e(TAG, "#Error : "+npe, npe);
showSnackBar();
}
}
@Override
public void onFailure(Call<AddFolderResponse> call, Throwable t) {
call.cancel();
Toast.makeText(PaidSubscriberDashboardActivity.this, "Something went wrong!", Toast.LENGTH_SHORT).show();
ProgressClass.getProgressInstance().stopProgress();
}
});
}else {
NetworkDialogHelper.getInstance().showDialog(PaidSubscriberDashboardActivity.this);
}
}
Monday 12 March 2018
Zoom ImageView like Web
STEP - 1 : XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp"> <ImageButton android:id="@+id/thumb_button_1" android:layout_width="100dp" android:layout_height="75dp" android:layout_marginRight="1dp" android:src="@drawable/thumb1" android:scaleType="centerCrop" android:contentDescription="@string/description_image_1" /> </LinearLayout> <!-- This initially-hidden ImageView will hold the expanded/zoomed version of the images above. Without transformations applied, it takes up the entire screen. To achieve the "zoom" animation, this view's bounds are animated from the bounds of the thumbnail button above, to its final laid-out bounds. --> <ImageView android:id="@+id/expanded_image" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="invisible" android:contentDescription="@string/description_zoom_touch_close" /> </FrameLayout>
STEP - 2 : Activity
public class ZoomActivity extends Activity { // Hold a reference to the current animator, // so that it can be canceled mid-way. private Animator mCurrentAnimator; // The system "short" animation time duration, in milliseconds. This // duration is ideal for subtle animations or animations that occur // very frequently. private int mShortAnimationDuration; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_zoom); // Hook up clicks on the thumbnail views. final View thumb1View = findViewById(R.id.thumb_button_1); thumb1View.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { zoomImageFromThumb(thumb1View, R.drawable.image1); } }); // Retrieve and cache the system's default "short" animation time. mShortAnimationDuration = getResources().getInteger( android.R.integer.config_shortAnimTime); } ... }
STEP - 3 : Zoom view From Local Code
private void zoomImageFromThumb(final View thumbView, int imageResId) { // If there's an animation in progress, cancel it // immediately and proceed with this one. if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } // Load the high-resolution "zoomed-in" image. final ImageView expandedImageView = (ImageView) findViewById( R.id.expanded_image); expandedImageView.setImageResource(imageResId); // Calculate the starting and ending bounds for the zoomed-in image. // This step involves lots of math. Yay, math. final Rect startBounds = new Rect(); final Rect finalBounds = new Rect(); final Point globalOffset = new Point(); // The start bounds are the global visible rectangle of the thumbnail, // and the final bounds are the global visible rectangle of the container // view. Also set the container view's offset as the origin for the // bounds, since that's the origin for the positioning animation // properties (X, Y). thumbView.getGlobalVisibleRect(startBounds); findViewById(R.id.container) .getGlobalVisibleRect(finalBounds, globalOffset); startBounds.offset(-globalOffset.x, -globalOffset.y); finalBounds.offset(-globalOffset.x, -globalOffset.y); // Adjust the start bounds to be the same aspect ratio as the final // bounds using the "center crop" technique. This prevents undesirable // stretching during the animation. Also calculate the start scaling // factor (the end scaling factor is always 1.0). float startScale; if ((float) finalBounds.width() / finalBounds.height() > (float) startBounds.width() / startBounds.height()) { // Extend start bounds horizontally startScale = (float) startBounds.height() / finalBounds.height(); float startWidth = startScale * finalBounds.width(); float deltaWidth = (startWidth - startBounds.width()) / 2; startBounds.left -= deltaWidth; startBounds.right += deltaWidth; } else { // Extend start bounds vertically startScale = (float) startBounds.width() / finalBounds.width(); float startHeight = startScale * finalBounds.height(); float deltaHeight = (startHeight - startBounds.height()) / 2; startBounds.top -= deltaHeight; startBounds.bottom += deltaHeight; } // Hide the thumbnail and show the zoomed-in view. When the animation // begins, it will position the zoomed-in view in the place of the // thumbnail. thumbView.setAlpha(0f); expandedImageView.setVisibility(View.VISIBLE); // Set the pivot point for SCALE_X and SCALE_Y transformations // to the top-left corner of the zoomed-in view (the default // is the center of the view). expandedImageView.setPivotX(0f); expandedImageView.setPivotY(0f); // Construct and run the parallel animation of the four translation and // scale properties (X, Y, SCALE_X, and SCALE_Y). AnimatorSet set = new AnimatorSet(); set .play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left, finalBounds.left)) .with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top, finalBounds.top)) .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScale, 1f)) .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScale, 1f)); set.setDuration(mShortAnimationDuration); set.setInterpolator(new DecelerateInterpolator()); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mCurrentAnimator = null; } @Override public void onAnimationCancel(Animator animation) { mCurrentAnimator = null; } }); set.start(); mCurrentAnimator = set; // Upon clicking the zoomed-in image, it should zoom back down // to the original bounds and show the thumbnail instead of // the expanded image. final float startScaleFinal = startScale; expandedImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } // Animate the four positioning/sizing properties in parallel, // back to their original values. AnimatorSet set = new AnimatorSet(); set.play(ObjectAnimator .ofFloat(expandedImageView, View.X, startBounds.left)) .with(ObjectAnimator .ofFloat(expandedImageView, View.Y,startBounds.top)) .with(ObjectAnimator .ofFloat(expandedImageView, View.SCALE_X, startScaleFinal)) .with(ObjectAnimator .ofFloat(expandedImageView, View.SCALE_Y, startScaleFinal)); set.setDuration(mShortAnimationDuration); set.setInterpolator(new DecelerateInterpolator()); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { thumbView.setAlpha(1f); expandedImageView.setVisibility(View.GONE); mCurrentAnimator = null; } @Override public void onAnimationCancel(Animator animation) { thumbView.setAlpha(1f); expandedImageView.setVisibility(View.GONE); mCurrentAnimator = null; } }); set.start(); mCurrentAnimator = set; } }); }
//IMAGEZOOM private void zoomImageFromThumb(final View thumbView, String imageResId) { // If there's an animation in progress, cancel it // immediately and proceed with this one. if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } // Load the high-resolution "zoomed-in" image. final ImageView expandedImageView = (ImageView) findViewById( R.id.expanded_image); // expandedImageView.setImageResource(imageResId); try { ProgressClass.getProgressInstance().showDialog(SubscriberDashboardActivity.this); Glide.with(SubscriberDashboardActivity.this).load(imageResId) .listener(new RequestListener<String, GlideDrawable>() { @Override public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) { ProgressClass.getProgressInstance().stopProgress(); if(e instanceof UnknownHostException) // progressBar.setVisibility(View.VISIBLE);// ProgressClass.getProgressInstance().showDialog(SubscriberDashboardActivity.this); ProgressClass.getProgressInstance().stopProgress(); return false; } @Override public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) { // progressBar.setVisibility(View.GONE); ProgressClass.getProgressInstance().stopProgress(); return false; } }) .error(R.drawable.profile_img1) .into(expandedImageView); } catch (Exception e) { e.printStackTrace(); } // Calculate the starting and ending bounds for the zoomed-in image. // This step involves lots of math. Yay, math. final Rect startBounds = new Rect(); final Rect finalBounds = new Rect(); final Point globalOffset = new Point(); // The start bounds are the global visible rectangle of the thumbnail, // and the final bounds are the global visible rectangle of the container // view. Also set the container view's offset as the origin for the // bounds, since that's the origin for the positioning animation // properties (X, Y). thumbView.getGlobalVisibleRect(startBounds); findViewById(R.id.container) .getGlobalVisibleRect(finalBounds, globalOffset); startBounds.offset(-globalOffset.x, -globalOffset.y); finalBounds.offset(-globalOffset.x, -globalOffset.y); // Adjust the start bounds to be the same aspect ratio as the final // bounds using the "center crop" technique. This prevents undesirable // stretching during the animation. Also calculate the start scaling // factor (the end scaling factor is always 1.0). float startScale; if ((float) finalBounds.width() / finalBounds.height() > (float) startBounds.width() / startBounds.height()) { // Extend start bounds horizontally startScale = (float) startBounds.height() / finalBounds.height(); float startWidth = startScale * finalBounds.width(); float deltaWidth = (startWidth - startBounds.width()) / 2; startBounds.left -= deltaWidth; startBounds.right += deltaWidth; } else { // Extend start bounds vertically startScale = (float) startBounds.width() / finalBounds.width(); float startHeight = startScale * finalBounds.height(); float deltaHeight = (startHeight - startBounds.height()) / 2; startBounds.top -= deltaHeight; startBounds.bottom += deltaHeight; } // Hide the thumbnail and show the zoomed-in view. When the animation // begins, it will position the zoomed-in view in the place of the // thumbnail. thumbView.setAlpha(0f); expandedImageView.setVisibility(View.VISIBLE); // Set the pivot point for SCALE_X and SCALE_Y transformations // to the top-left corner of the zoomed-in view (the default // is the center of the view). expandedImageView.setPivotX(0f); expandedImageView.setPivotY(0f); // Construct and run the parallel animation of the four translation and // scale properties (X, Y, SCALE_X, and SCALE_Y). AnimatorSet set = new AnimatorSet(); set .play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left, finalBounds.left)) .with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top, finalBounds.top)) .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScale, 1f)) .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScale, 1f)); set.setDuration(mShortAnimationDuration); set.setInterpolator(new DecelerateInterpolator()); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mCurrentAnimator = null; } @Override public void onAnimationCancel(Animator animation) { mCurrentAnimator = null; } }); set.start(); mCurrentAnimator = set; // Upon clicking the zoomed-in image, it should zoom back down // to the original bounds and show the thumbnail instead of // the expanded image. final float startScaleFinal = startScale; expandedImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } // Animate the four positioning/sizing properties in parallel, // back to their original values. AnimatorSet set = new AnimatorSet(); set.play(ObjectAnimator .ofFloat(expandedImageView, View.X, startBounds.left)) .with(ObjectAnimator .ofFloat(expandedImageView, View.Y,startBounds.top)) .with(ObjectAnimator .ofFloat(expandedImageView, View.SCALE_X, startScaleFinal)) .with(ObjectAnimator .ofFloat(expandedImageView, View.SCALE_Y, startScaleFinal)); set.setDuration(mShortAnimationDuration); set.setInterpolator(new DecelerateInterpolator()); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { thumbView.setAlpha(1f); expandedImageView.setVisibility(View.GONE); mCurrentAnimator = null; } @Override public void onAnimationCancel(Animator animation) { thumbView.setAlpha(1f); expandedImageView.setVisibility(View.GONE); mCurrentAnimator = null; } }); set.start(); mCurrentAnimator = set; } }); }
Subscribe to:
Posts (Atom)