在列表视图中快速滚动时崩溃 android
Crashes when scrolling fast in listview android
我有一个列表视图,当滚动时,列表视图中间的项目被放大并且它的颜色发生变化。
但是我有一个问题,当我快速滚动时它会崩溃。
我的代码位于下方。
谁能告诉我是什么导致了这个问题?
谢谢
myActivity.java
public class myActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_entekhb_zaman);
txtday=(TextView)findViewById(R.id.txtday);
txtdayok=(TextView)findViewById(R.id.txtdayok);
listviewday = (ListView) findViewById(R.id.listday);
listday.add("");
listday.add("1");
listday.add("2");
listday.add("3");
listday.add("4");
listday.add("");
adapterday=new Custom_List_Day(this,android.R.layout.simple_list_item_1,listday);
listviewday.setAdapter(adapterday);
listviewday.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
if (scrollState == SCROLL_STATE_IDLE) {
View itemView = view.getChildAt(0);
int top = Math.abs(itemView.getTop());
int bottom = Math.abs(itemView.getBottom());
int scrollBy = top >= bottom ? bottom : -top;
if (scrollBy == 0) {
return;
}
smoothScrollDeferred(scrollBy, (ListView)view);
}
}
private void smoothScrollDeferred(final int scrollByF,
final ListView viewF) {
final Handler h = new Handler();
h.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
viewF.smoothScrollBy(scrollByF, 200);
}
});
}
@Override
public void onScroll(AbsListView arg0, int firstVisibleItem, int visibleItemCount, int totalItemCount){
Log.i("Scroll","first "+firstVisibleItem+", visibleItemCount "+visibleItemCount+",totalCount "+totalItemCount);
int center = firstVisibleItem+(visibleItemCount)/2 ;
if(currentLargedPosition != center){
enlargeMiddleView(currentLargedPosition-firstVisibleItem, center-firstVisibleItem);
currentLargedPosition = center;
txtdayok.setText(listday.get(currentLargedPosition));
}
}
});
}
void enlargeMiddleView(int oldPosition, int newPosition){
// get enlarged view and make it return default size
TextView newTextView = (TextView)listviewday.getChildAt(oldPosition).findViewById(R.id.txtday3);
newTextView.setTextSize(22);
newTextView.setTextColor(getResources().getColor(R.color.white));
// get the current center view and make it bigger
TextView oldTextView = (TextView)listviewday.getChildAt(newPosition).findViewById(R.id.txtday3);
oldTextView.setTextSize(28);
oldTextView.setTextColor(getResources().getColor(R.color.sormeii));
}
}
Custom_List_Day
public class Custom_List_Day extends ArrayAdapter<String> {
private final Activity context;
private final ArrayList<String> name;
private final int resource;
public Custom_List_Day(Activity context,int resource, ArrayList<String> name) {
super(context, resource, name);
this.context = context;
this.name = name ;
this.resource=resource;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return name.size();
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public int getViewTypeCount() {
return super.getViewTypeCount();
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater infalter = context.getLayoutInflater();
View rowLayout = null;
if (convertView == null) {
// inflating the row
rowLayout = infalter.inflate(this.resource, parent,false);
} else {
rowLayout = convertView;
}
TextView txtName = (TextView) rowLayout.findViewById(R.id.txtday3);
txtName.setText(name.get(position));
return rowLayout ;
}
}
list_day.xml
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/colorPrimary"
xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="4dp">
<TextView
android:id="@+id/txtday3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="شنبه - ۹خرداد"
android:textColor="@color/white"
android:textSize="22sp"/>
</LinearLayout>
当我慢慢滚动时,没有任何问题,程序运行正常。
但是当我快速滚动时,程序崩溃了。
logcat错误
07-15 12:32:45.607 14920-14920/anjam.carno E/AndroidRuntime: FATAL EXCEPTION: main
Process: anjam.carno, PID: 14920
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at anjam.carno.ActivityEntekhabZaman.enlargeMiddleView2(ActivityEntekhabZaman.java:232)
at anjam.carno.ActivityEntekhabZaman.onScroll(ActivityEntekhabZaman.java:189)
at android.widget.AbsListView.invokeOnItemScrollListener(AbsListView.java:1519)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5245)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4668)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:549)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
IMO,200 毫秒的延迟是导致崩溃的原因。
在我的脑海中,
改变
if(currentLargedPosition != center){
enlargeMiddleView(currentLargedPosition-firstVisibleItem, center-firstVisibleItem);
currentLargedPosition = center;
txtdayok.setText(listday.get(currentLargedPosition));
}
在onScroll
到
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(210);
runOnUiThread(new Runnable() {
@Override
public void run() {
if(currentLargedPosition != center){
enlargeMiddleView(currentLargedPosition-firstVisibleItem, center-firstVisibleItem);
currentLargedPosition = center;
txtdayok.setText(listday.get(currentLargedPosition));
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
当然,滚动时会出现应用滞后的情况。但这是我能想到的唯一方法,不会改变你的核心逻辑。另外,这只是一个理论,我不能 100% 确定它会起作用。
首先,我建议您阅读Standing coding guidelines for android。它将提高您的编码标准。
其次,您需要删除处理程序。从您的代码来看,您想要将 ListView
对齐到中间。请看一下RecyclerView
。如果你想在中间添加 snap link Linear Snap Helper 会帮助你。
但是,如果您想修改代码,我建议您进行以下更改
listviewday.setOnScrollListener(new AbsListView.OnScrollListener()
{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
// TODO Auto-generated method stub
if (scrollState == SCROLL_STATE_IDLE)
{
View itemView = view.getChildAt(0);
int top = Math.abs(itemView.getTop());
int bottom = Math.abs(itemView.getBottom());
int scrollBy = top >= bottom ? bottom : -top;
if (scrollBy == 0)
{
return;
}
view.smoothScrollBy(scrollBy, 200);
}
}
@Override
public void onScroll(AbsListView arg0, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
if (visibleItemCount != 0)
{
if (oldTextView != null)
{
oldTextView.setTextSize(22);
oldTextView.setTextColor(Color.WHITE);
oldTextView = null;
}
final int midPosition = visibleItemCount - (visibleItemCount / 2);
final TextView listItem = (TextView) listviewday.getChildAt(midPosition - 1).findViewById(R.id.txtday3);
listItem.setTextSize(26);
listItem.setTextColor(Color.BLACK);
oldTextView = listItem;
}
}
});
我有一个列表视图,当滚动时,列表视图中间的项目被放大并且它的颜色发生变化。 但是我有一个问题,当我快速滚动时它会崩溃。 我的代码位于下方。 谁能告诉我是什么导致了这个问题? 谢谢
myActivity.java
public class myActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_entekhb_zaman);
txtday=(TextView)findViewById(R.id.txtday);
txtdayok=(TextView)findViewById(R.id.txtdayok);
listviewday = (ListView) findViewById(R.id.listday);
listday.add("");
listday.add("1");
listday.add("2");
listday.add("3");
listday.add("4");
listday.add("");
adapterday=new Custom_List_Day(this,android.R.layout.simple_list_item_1,listday);
listviewday.setAdapter(adapterday);
listviewday.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
if (scrollState == SCROLL_STATE_IDLE) {
View itemView = view.getChildAt(0);
int top = Math.abs(itemView.getTop());
int bottom = Math.abs(itemView.getBottom());
int scrollBy = top >= bottom ? bottom : -top;
if (scrollBy == 0) {
return;
}
smoothScrollDeferred(scrollBy, (ListView)view);
}
}
private void smoothScrollDeferred(final int scrollByF,
final ListView viewF) {
final Handler h = new Handler();
h.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
viewF.smoothScrollBy(scrollByF, 200);
}
});
}
@Override
public void onScroll(AbsListView arg0, int firstVisibleItem, int visibleItemCount, int totalItemCount){
Log.i("Scroll","first "+firstVisibleItem+", visibleItemCount "+visibleItemCount+",totalCount "+totalItemCount);
int center = firstVisibleItem+(visibleItemCount)/2 ;
if(currentLargedPosition != center){
enlargeMiddleView(currentLargedPosition-firstVisibleItem, center-firstVisibleItem);
currentLargedPosition = center;
txtdayok.setText(listday.get(currentLargedPosition));
}
}
});
}
void enlargeMiddleView(int oldPosition, int newPosition){
// get enlarged view and make it return default size
TextView newTextView = (TextView)listviewday.getChildAt(oldPosition).findViewById(R.id.txtday3);
newTextView.setTextSize(22);
newTextView.setTextColor(getResources().getColor(R.color.white));
// get the current center view and make it bigger
TextView oldTextView = (TextView)listviewday.getChildAt(newPosition).findViewById(R.id.txtday3);
oldTextView.setTextSize(28);
oldTextView.setTextColor(getResources().getColor(R.color.sormeii));
}
}
Custom_List_Day
public class Custom_List_Day extends ArrayAdapter<String> {
private final Activity context;
private final ArrayList<String> name;
private final int resource;
public Custom_List_Day(Activity context,int resource, ArrayList<String> name) {
super(context, resource, name);
this.context = context;
this.name = name ;
this.resource=resource;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return name.size();
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public int getViewTypeCount() {
return super.getViewTypeCount();
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater infalter = context.getLayoutInflater();
View rowLayout = null;
if (convertView == null) {
// inflating the row
rowLayout = infalter.inflate(this.resource, parent,false);
} else {
rowLayout = convertView;
}
TextView txtName = (TextView) rowLayout.findViewById(R.id.txtday3);
txtName.setText(name.get(position));
return rowLayout ;
}
}
list_day.xml
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/colorPrimary"
xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="4dp">
<TextView
android:id="@+id/txtday3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="شنبه - ۹خرداد"
android:textColor="@color/white"
android:textSize="22sp"/>
</LinearLayout>
当我慢慢滚动时,没有任何问题,程序运行正常。 但是当我快速滚动时,程序崩溃了。 logcat错误
07-15 12:32:45.607 14920-14920/anjam.carno E/AndroidRuntime: FATAL EXCEPTION: main
Process: anjam.carno, PID: 14920
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at anjam.carno.ActivityEntekhabZaman.enlargeMiddleView2(ActivityEntekhabZaman.java:232)
at anjam.carno.ActivityEntekhabZaman.onScroll(ActivityEntekhabZaman.java:189)
at android.widget.AbsListView.invokeOnItemScrollListener(AbsListView.java:1519)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5245)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4668)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:549)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
IMO,200 毫秒的延迟是导致崩溃的原因。 在我的脑海中,
改变
if(currentLargedPosition != center){
enlargeMiddleView(currentLargedPosition-firstVisibleItem, center-firstVisibleItem);
currentLargedPosition = center;
txtdayok.setText(listday.get(currentLargedPosition));
}
在onScroll
到
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(210);
runOnUiThread(new Runnable() {
@Override
public void run() {
if(currentLargedPosition != center){
enlargeMiddleView(currentLargedPosition-firstVisibleItem, center-firstVisibleItem);
currentLargedPosition = center;
txtdayok.setText(listday.get(currentLargedPosition));
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
当然,滚动时会出现应用滞后的情况。但这是我能想到的唯一方法,不会改变你的核心逻辑。另外,这只是一个理论,我不能 100% 确定它会起作用。
首先,我建议您阅读Standing coding guidelines for android。它将提高您的编码标准。
其次,您需要删除处理程序。从您的代码来看,您想要将 ListView
对齐到中间。请看一下RecyclerView
。如果你想在中间添加 snap link Linear Snap Helper 会帮助你。
但是,如果您想修改代码,我建议您进行以下更改
listviewday.setOnScrollListener(new AbsListView.OnScrollListener()
{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
// TODO Auto-generated method stub
if (scrollState == SCROLL_STATE_IDLE)
{
View itemView = view.getChildAt(0);
int top = Math.abs(itemView.getTop());
int bottom = Math.abs(itemView.getBottom());
int scrollBy = top >= bottom ? bottom : -top;
if (scrollBy == 0)
{
return;
}
view.smoothScrollBy(scrollBy, 200);
}
}
@Override
public void onScroll(AbsListView arg0, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
if (visibleItemCount != 0)
{
if (oldTextView != null)
{
oldTextView.setTextSize(22);
oldTextView.setTextColor(Color.WHITE);
oldTextView = null;
}
final int midPosition = visibleItemCount - (visibleItemCount / 2);
final TextView listItem = (TextView) listviewday.getChildAt(midPosition - 1).findViewById(R.id.txtday3);
listItem.setTextSize(26);
listItem.setTextColor(Color.BLACK);
oldTextView = listItem;
}
}
});