#android #listview #animation
#Android #listview #Анимация
Вопрос:
У меня возникла некоторая проблема с анимацией ListView: как я могу реализовать анимацию «исчезновения» элементов в ListView? Мне нужно иметь только шесть элементов на экране и такую анимацию, как на картинке.
Мне удалось создать анимацию «затухания», и это не совсем то, что мне нужно.
package com.example.testmalyutinoleksandr;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private ListView listview;
private TextView textView;
private Context con;
private static final String LABELSKEY = "myListLabels";
private static final String COUNTERSKEY = "myListCounters";
private String values [];
private int counters [];
private static Calendar currentDate;
private Timer timer;
static {
currentDate = GregorianCalendar.getInstance();
}
public void onCreate(Bundle savedInstanceState) {
setTheme(android.R.style.Theme_Black_NoTitleBar);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
con = this;
listview = (ListView) findViewById(R.id.myListView);
textView = (TextView) findViewById(R.id.timeTextView);
if (savedInstanceState != null amp;amp; savedInstanceState.containsKey(LABELSKEY))
{
values = savedInstanceState.getStringArray(LABELSKEY);
counters = savedInstanceState.getIntArray(COUNTERSKEY);
}
else
{
values = DataLoader.getTitles(getApplication());
counters = new int [] {0,0,0,0,0,0,0,0,0,0};
}
SimpleListAdapter adapter = new SimpleListAdapter(this, values, counters);
listview.setAdapter(adapter);
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
currentDate = GregorianCalendar.getInstance();
int hour = currentDate.get(Calendar.HOUR_OF_DAY);
int minutes = currentDate.get(Calendar.MINUTE);
int seconds = currentDate.get(Calendar.SECOND);
textView.setText( hour ":" (minutes<10?"0":"") minutes ":" (seconds<10?"0":"") seconds);
}
}
);
}
} , 1, 1*1000);
listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
TextView counterTextView = (TextView) view.findViewById(R.id.counterTextView);
int counter = Integer.valueOf(counterTextView.getText().toString());
counter ;
counterTextView.setText(counter "");
MainActivity.this.counters[position] = counter;
Toast.makeText(getApplication(), "Нажата кнопка " (position 1), Toast.LENGTH_SHORT).show();
}
});
listview.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
final int position, long id) {
AlertDialog.Builder alert = new AlertDialog.Builder(con);
alert.setTitle("Title");
alert.setMessage("Message");
final EditText input = new EditText(con);
input.setText("");
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// the adapter you set in the listView.setAdapter();
values[position] = input.getText().toString();
SimpleListAdapter adapter = new SimpleListAdapter(con, values, counters);
listview.setAdapter(adapter);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.show();
return true;
}
});
}
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putStringArray(LABELSKEY, values);
outState.putIntArray(COUNTERSKEY, counters);
}
}
И вот код адаптера:
package com.example.testmalyutinoleksandr;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class SimpleListAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
private final int[] counters;
private ArrayList<Drawable> icons;
private ArrayList<Drawable> bcgnd;
public SimpleListAdapter(Context context, String[] values, int [] counters1) {
super(context, R.layout.one_item, values);
this.context = context;
this.values = values;
this.counters = counters1;
this.icons = DataLoader.getIconsRandomly(context);
this.bcgnd = DataLoader.getBackgrounds(context);
}
static class ViewHolder {
public ImageView iconImageView;
public TextView titleTextView;
public TextView counterTextView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
View rowView = convertView;
if(rowView == null){
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
rowView = inflater.inflate(R.layout.one_item, parent, false);
holder = new ViewHolder();
holder.iconImageView = (ImageView) rowView.findViewById(R.id.iconImageView);
holder.titleTextView = (TextView) rowView.findViewById(R.id.titleTextView);
holder.counterTextView = (TextView) rowView.findViewById(R.id.counterTextView);
rowView.setTag(holder);
}else{
holder = (ViewHolder) rowView.getTag();
}
holder.iconImageView.setImageDrawable(icons.get(position));
rowView.setBackgroundDrawable(bcgnd.get(position));
holder.titleTextView.setText(values[position]);
holder.counterTextView.setText(counters[position] "");
Animation animation = null;
animation = AnimationUtils.loadAnimation(context, R.anim.test_set);
animation.setDuration(500);
rowView.startAnimation(animation);
animation = null;
return rowView;
}
}
Итак, можете ли вы сказать мне, что мне делать?
РЕДАКТИРОВАТЬ 1
Мне удалось сделать этот тип анимации с помощью кода
package com.example.testmalyutinoleksandr;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.ScaleAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private ListView listview;
private TextView textView;
private Context con;
private static final String LABELSKEY = "myListLabels";
private static final String COUNTERSKEY = "myListCounters";
private String values [];
private int counters [];
private static Calendar currentDate;
private Timer timer;
SimpleListAdapter adapter;
private static volatile float prevX= 1;
//private static int prevY = 1;
private static volatile int width;
private static volatile int height;
private static volatile boolean flag = true;
AbsListView view;
int visibleItemCount;
static {
currentDate = GregorianCalendar.getInstance();
}
public void onCreate(Bundle savedInstanceState) {
setTheme(android.R.style.Theme_Black_NoTitleBar);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
con = this;
listview = (ListView) findViewById(R.id.myListView);
textView = (TextView) findViewById(R.id.timeTextView);
if (savedInstanceState != null amp;amp; savedInstanceState.containsKey(LABELSKEY))
{
values = savedInstanceState.getStringArray(LABELSKEY);
counters = savedInstanceState.getIntArray(COUNTERSKEY);
}
else
{
values = DataLoader.getTitles(getApplication());
counters = new int [] {0,0,0,0,0,0,0,0,0,0};
}
adapter = new SimpleListAdapter(this, values, counters);
listview.setAdapter(adapter);
Log.d("myLogs", "onCreate run");
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
currentDate = GregorianCalendar.getInstance();
int hour = currentDate.get(Calendar.HOUR_OF_DAY);
int minutes = currentDate.get(Calendar.MINUTE);
int seconds = currentDate.get(Calendar.SECOND);
textView.setText( hour ":" (minutes<10?"0":"") minutes ":" (seconds<10?"0":"") seconds);
}
}
);
}
} , 1, 1*1000);
listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
TextView counterTextView = (TextView) view.findViewById(R.id.counterTextView);
int counter = Integer.valueOf(counterTextView.getText().toString());
counter ;
counterTextView.setText(counter "");
MainActivity.this.counters[position] = counter;
Toast.makeText(getApplication(), "Нажата кнопка " (position 1), Toast.LENGTH_SHORT).show();
}
});
listview.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
final int position, long id) {
AlertDialog.Builder alert = new AlertDialog.Builder(con);
alert.setTitle("Title");
alert.setMessage("Message");
final EditText input = new EditText(con);
input.setText("");
alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// the adapter you set in the listView.setAdapter();
values[position] = input.getText().toString();
SimpleListAdapter adapter = new SimpleListAdapter(con, values, counters);
listview.setAdapter(adapter);
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.show();
return true;
}
});
listview.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
int pos = view.getFirstVisiblePosition();
ScaleAnimation scaleAnimation = new ScaleAnimation(MainActivity.prevX, (float)(MainActivity.prevX 0.001), MainActivity.prevX, (float)(MainActivity.prevX 0.001), 300, 100);
scaleAnimation.setDuration(1);
Log.d("myLogs", "Params: " MainActivity.prevX);
View firstView = view.getChildAt(0);
firstView.setAnimation(scaleAnimation);
firstView.startAnimation(scaleAnimation);
firstView.invalidate();
//}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
MainActivity.this.view = view;
MainActivity.this.visibleItemCount = visibleItemCount;
runOnUiThread(new Runnable() {
@Override
public void run() {
int [] location = {-1,-1};
MainActivity.this.view.getLocationOnScreen(location);
if(location[0] != 0 amp;amp; location[1] != 0){
if(MainActivity.this.visibleItemCount == 6){
for(int i=0; i<MainActivity.this.visibleItemCount; i ){
View middleWantedView = listview.getChildAt(i);
if(MainActivity.flag){
MainActivity.height = middleWantedView.getHeight();
MainActivity.width = middleWantedView.getWidth();
MainActivity.flag = false;
}
middleWantedView.setScaleX(1);
middleWantedView.setScaleY(1);
}
}
if(MainActivity.this.visibleItemCount == 7){
View wantedView = listview.getChildAt(0);
wantedView.getLocationOnScreen(location);
float scaling = (float) (((float)location[1] - 150.0)/100.0);
Log.d("myLogs", "Scalling:" scaling);
if(MainActivity.prevX == scaling)
scaling = (float) (scaling 0.001);
ScaleAnimation scaleAnimation = new ScaleAnimation(MainActivity.prevX, scaling, MainActivity.prevX, scaling, 300, 100);
scaleAnimation.setDuration(1);
wantedView.setAnimation(scaleAnimation);
wantedView.startAnimation(scaleAnimation);
View secondWantedView = listview.getChildAt(MainActivity.this.visibleItemCount-1);
float scaling2 = (float) (1.0 - scaling);
int padding = (-1) * (250 - location[1]);
padding = (int) (padding - (padding * 0.5));
Log.d("myLogs", "Padding:" padding);
scaleAnimation = new ScaleAnimation((float) (1.0 - MainActivity.prevX), scaling2, (float) (1.0 -MainActivity.prevX), scaling2, 300, padding);
secondWantedView.setAnimation(scaleAnimation);
secondWantedView.startAnimation(scaleAnimation);
MainActivity.prevX = scaling;
secondWantedView.setScaleX(scaling2);
secondWantedView.setScaleY(scaling2);
}
}
}});
}});
};
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putStringArray(LABELSKEY, values);
outState.putIntArray(COUNTERSKEY, counters);
}
}`
Пока прокрутка не продолжается, анимация хорошая. Когда прокрутка останавливается, первый переходит в полный размер, вместо xx% от полного размера, и у последнего элемента также есть проблемы.
Ответ №1:
Может быть, вы можете попробовать это:
View row = findViewById(R.id.myrow);
if(row.getVisibility() == View.VISIBLE) {
row.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
row.setVisibility(View.INVISIBLE);
} else {
row.startAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));
row.setVisibility(View.VISIBLE);
}
Комментарии:
1. Я пробовал, но это не совсем то, что мне нужно. Я переписываю вопрос.