I have a list view that when scrolling, the item in the middle of the list view is enlarged and its color changes. But I have a problem, and it crashes when I scroll fast. My code is located below. Can anyone tell me what is causing the problem? Thanks
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>
When I slowly scroll, I have no problems and the program works. But when I scroll fast, the program crashes. logcat error
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)
Firstly, I would like to suggest you to read Standing coding guidelines for android. It will improve your coding standards.
Secondly you need to remove the handler. Judging from your code, you want to snap the ListView
to middle. Please have a look at RecyclerView
. If you want to add snap to middle this link Linear Snap Helper will help you.
However if you want to modify your code I suggest you do following changes
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;
}
}
});