我有一个列表视图,滚动时,列表视图中间的项目被放大并且其颜色改变。 但是我有一个问题,当我快速滚动时会崩溃。 我的代码位于下面。 谁能告诉我是什么引起了这个问题? 谢谢
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$2.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)
答案 0 :(得分:1)
首先,我建议您阅读Standing coding guidelines for android。它将提高您的编码标准。
第二,您需要删除处理程序。从您的代码来看,您想将ListView
对齐到中间。请查看RecyclerView
。如果您想在中间添加快照,则此链接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;
}
}
});
答案 1 :(得分:0)
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%会奏效。