Even though I checked some threads, I'm having problems to use both the OnTouchListener and the OnClickListener inside of a fragment.
Custom class:
import android.content.Context;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class Gestures implements View.OnTouchListener
{
private GestureDetector gestureDetector = null;
public Gestures()
{
gestureDetector = new GestureDetector(new GestureListener());
}
public boolean onTouch(View view, MotionEvent motionEvent)
{
boolean res = gestureDetector.onTouchEvent(motionEvent);
return res;
}
private final class GestureListener extends GestureDetector.SimpleOnGestureListener
{
private static final int SWIPE_THRESHOLD = 50;
private static final int SWIPE_VELOCITY_THRESHOLD = 50;
#Override
public void onLongPress(MotionEvent motionEvent)
{
onLongClick();
super.onLongPress(motionEvent);
}
#Override
public boolean onDown(MotionEvent motionEvent)
{
return true;
}
#Override
public boolean onFling(MotionEvent motionEvent1, MotionEvent motionEvent2, float velocityX, float velocityY)
{
boolean result = false;
try
{
float differenceX = motionEvent2.getX() - motionEvent1.getX();
float differenceY = motionEvent2.getY() - motionEvent1.getY();
if (Math.abs(differenceX) < Math.abs(differenceY))
{
if (Math.abs(differenceY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD)
{
if (differenceY > 0)
{
result = onSwipeBottom();
}
else
{
result = onSwipeTop();
}
}
else
{
result = nothing();
}
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
return result;
}
}
public boolean nothing()
{
return false;
}
public boolean onSwipeTop()
{
return false;
}
public boolean onSwipeBottom()
{
return false;
}
public boolean onLongClick()
{
return false;
}
}
Fragment:
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
public class Fragment1 extends Fragment implements View.OnClickListener, View.OnTouchListener
{
ConstraintLayout constraintLayoutOne, constraintLayoutTwo;
#Override public void onResume()
{
super.onResume();
constraintLayoutOne = getActivity().findViewById(R.id.constraint_layout_one); // Link variable to ID
constraintLayoutTwo = getActivity().findViewById(R.id.constraint_layout_two); // Link variable to ID
getActivity().findViewById(R.id.constraint_layout_one).setOnClickListener(this);
getActivity().findViewById(R.id.constraint_layout_two).setOnClickListener(this);
getActivity().findViewById(R.id.constraint_layout_one).setOnTouchListener(this);
getActivity().findViewById(R.id.constraint_layout_two).setOnTouchListener(this);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState)
{
View fragment1 = inflater.inflate(R.layout.fragment1, container, false); // Link view and layout
return fragment1;
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent)
{
switch (view.getId())
{
case R.id.constraint_layout_one:
case R.id.constraint_layout_two:
view.setOnTouchListener(new Gestures()
{
public boolean onSwipeTop()
{
showToast("swiped up");
return false;
}
public boolean onSwipeBottom()
{
showToast("swiped down");
return false;
}
});
}
return false;
}
#Override
public void onClick(View view)
{
if (view.getId() == R.id.constraint_layout_one)
{
showToast("button one clicked");
}
if (view.getId() == R.id.constraint_layout_two)
{
showToast("button two clicked");
}
}
public void showToast(String text)
{
Toast toast = Toast.makeText(getContext(), text, Toast.LENGTH_SHORT); // Generate toast message
toast.setGravity(Gravity.CENTER| Gravity.CENTER, 0, -1); // Change y-Position of toast a bit
toast.show(); // Show toast for 4 seconds
}
}
The two problems:
1)
When I start the app, the swipes don't work. Nothing happens when I swipe.
I have to perform 2 swipes to get it to work.
After that, I can swipe as often as I want.
2)
The clicks only work one time.
After the first click, no further clicks get recognized anymore (for the clicked view)
Same happens when I do two swipes - no clicks anymore.
Any help will be appreciated!
I tried something completely different. -> onInterceptTouchEvent
I created a helper class named RootView:
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.constraintlayout.widget.ConstraintLayout;
public class RootLayout extends ConstraintLayout
{
public RootLayout(Context context)
{
super(context);
}
public RootLayout(Context context, AttributeSet attributeSet)
{
super(context, attributeSet);
}
public RootLayout(Context context, AttributeSet attributeSet, int defStyleAttribute)
{
super(context, attributeSet, defStyleAttribute);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent motionEvent)
{
return true;
}
}
Inside of my xml file, I changed the ConstraintLayout to the RootLayout:
<com.example.testSwipeApp.RootLayout 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:layout_editor_absoluteY="81dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraint_layout_two"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#E91E63"
android:clickable="true"
android:focusable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.4"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="1" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraint_layout_one"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#3F51B5"
android:clickable="false"
android:focusable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="1" />
<TextView
android:id="#+id/text_view_header"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#000000"
android:gravity="center_horizontal"
android:paddingTop="2dp"
android:textColor="#ffffff"
android:textSize="15sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.10"
app:layout_constraintHorizontal_bias="0.503"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</com.example.testSwipeApp.RootLayout>
The fragment1.java looks like this:
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
public class Fragment1 extends Fragment implements View.OnClickListener
{
ConstraintLayout constraintLayoutOne, constraintLayoutTwo;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState)
{
View fragment1 = inflater.inflate(R.layout.fragment1, container, false); // Link view and layout
constraintLayoutOne = fragment1.findViewById(R.id.constraint_layout_one); // Link variable to ID
constraintLayoutTwo = fragment1.findViewById(R.id.constraint_layout_two); // Link variable to ID
fragment1.findViewById(R.id.constraint_layout_one).setOnClickListener(this);
fragment1.findViewById(R.id.constraint_layout_two).setOnClickListener(this);
fragment1.setOnTouchListener(new Gestures()
{
public boolean onSwipeTop()
{
Toast.makeText(getContext(), "Swiped up", Toast.LENGTH_SHORT).show();
return false;
}
public boolean onSwipeBottom()
{
Toast.makeText(getContext(), "Swiped down", Toast.LENGTH_SHORT).show();
return false;
}
});
return fragment1;
}
#Override
public void onClick(View view)
{
switch (view.getId())
{
case R.id.constraint_layout_one:
case R.id.constraint_layout_two:
showToast("clicked");
break;
}
}
public void showToast(String text)
{
Toast toast = Toast.makeText(getContext(), text, Toast.LENGTH_SHORT); // Generate toast message
toast.setGravity(Gravity.CENTER| Gravity.CENTER, 0, -1); // Change y-Position of toast a bit
toast.show(); // Show toast for 4 seconds
}
}
The problem:
Clicks don't get accepted anymore.
Even though this version works worse, I prefer this way rather than the old one.
Any help will be appreciated!
Related
I am trying to implement RecyclerView using ParseObject but on my screen nothing is showing up!
Following is the code for the activity where recycler view is to implemented.
AdminShowStudentId.java
package com.example.Aphexams;
import android.content.Intent;
import android.os.Bundle;
import android.app.Activity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Adapter;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.Toast;
import com.parse.FindCallback;
import com.parse.GetCallback;
import com.parse.ParseException;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import com.parse.ParseQueryAdapter;
import java.util.ArrayList;
import java.util.List;
//import app.android.project.com.olexam.R;
public class AdminShowStudentId extends Activity {
private RecyclerView recycleerviewDetails;
private RecyclerView.LayoutManager layoutManager;
private StudentIdAdapter studentidAdapter;
private ArrayList<StudentId> studentidarraylist;
private boolean notComplete = true;
private String studId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_show_student_id);
final StudentId studentId=new StudentId();
studentidarraylist=new ArrayList<StudentId>();
if(notComplete) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("studAuth");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
for (ParseObject object : objects) {
String studentid = (String) object.get("StudUserName");
studentId.setStudentId(studentid);
studentidarraylist.add(studentId);
}
//is it fetching or not
} else {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
notComplete=false;
}
recycleerviewDetails=(RecyclerView)findViewById(R.id.studentidrecyclerview);
if (recycleerviewDetails != null)
{
recycleerviewDetails.setHasFixedSize(true);
}
/*fetching data from the database*/
studentidAdapter=new StudentIdAdapter(studentidarraylist);
recycleerviewDetails.setAdapter(studentidAdapter);
studentidAdapter.notifyDataSetChanged();
layoutManager=new GridLayoutManager(this,1);
recycleerviewDetails.setLayoutManager(layoutManager);
recycleerviewDetails.addOnItemTouchListener(new RecyclerViewListener(AdminShowStudentId.this,new RecyclerViewListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
studId=studentidarraylist.get(position).getStudentId();
Intent i=new Intent(AdminShowStudentId.this,ViewStudent.class);
i.putExtra("studId",studId);
}
}));
}
}
following is the code for StudentIdAdapter.java
package com.example.Aphexams;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by HP on 24-05-2018.
*/
public class StudentIdAdapter extends RecyclerView.Adapter<StudentIdAdapter.StudentIdViewHolder>
{
private List<StudentId> studentIdList;
public StudentIdAdapter(ArrayList<StudentId> studentidarraylist) {
this.studentIdList=studentidarraylist;
}
#Override
public StudentIdViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.studentid_row,parent,false);
StudentIdViewHolder studentIdViewHolder=new StudentIdViewHolder(view);
return studentIdViewHolder;
}
#Override
public void onBindViewHolder(StudentIdViewHolder holder, int position) {
StudentId studentid= studentIdList.get(position);
holder.tvStudentId.setText(studentid.getStudentId());
// holder.tvanswerdate.setText(answer.getAnswerdate());
}
#Override
public int getItemCount() {
return 0;
}
public class StudentIdViewHolder extends RecyclerView.ViewHolder
{
private TextView tvStudentId;
public StudentIdViewHolder(View itemView)
{
super(itemView);
tvStudentId=(TextView)itemView.findViewById(R.id.studentidtv);
}
}
}
following is the code for RecyclerViewListener.java
package com.example.Aphexams;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
/**
* Created by HP on 24-05-2018.
*/
public class RecyclerViewListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
GestureDetector mGestureDetector;
public interface OnItemClickListener
{
public void onItemClick(View view, int position);
}
public RecyclerViewListener(Context context, OnItemClickListener listener)
{
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener()
{
#Override public boolean onSingleTapUp(MotionEvent e)
{
return true;
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View childView = rv.findChildViewUnder(e.getX(),e.getY());
if(childView != null && mListener != null && mGestureDetector.onTouchEvent(e))
{
mListener.onItemClick(childView, rv.getChildAdapterPosition(childView));
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
Following is the code for StudentId.java
package com.example.Aphexams;
/**
* Created by HP on 24-05-2018.
*/
public class StudentId {
private String StudentId;
public String getStudentId() {
return StudentId;
}
public void setStudentId(String studentId) {
StudentId = studentId;
}
}
following is my code for layout of activity_admin_show_student_id.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.Aphexams.AdminShowStudentId">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/studentidrecyclerview">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.NestedScrollView>
following is the code for studentid
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="20dp"
android:id="#+id/studentidtv"
android:textSize="16dp"
android:text="now you see me!"/>
</LinearLayout>
I have tried to take some help from How to use ParseObjects with a RecyclerView?.
Taking a look at you code, I guess the error is that you set you adapter with a empty list at first, then you add items to your list in your FindCallback but you never tell the list to re-render the items.
Have you checked when you set you adapter if the list is actually populated? Because since your query is running in background, there is a chance the below lines will be execute before your query finishes.
studentidAdapter=new StudentIdAdapter(studentidarraylist);
recycleerviewDetails.setAdapter(studentidAdapter);
To achieve what you are trying to do, I guess you should call
studentidAdapter=new StudentIdAdapter(studentidarraylist);
recycleerviewDetails.setAdapter(studentidAdapter);
studentidAdapter.notifyDataSetChanged();
inside your FindCallback, when you are sure your list is populated.
So, I made the following changes in my code.
AdminShowStudentId.java
As suggested by Thiago Loddi
public class AdminShowStudentId extends Activity {
private RecyclerView recycleerviewDetails;
private RecyclerView.LayoutManager layoutManager;
private StudentIdAdapter studentidAdapter;
private ArrayList<StudentId> studentidarraylist;
private boolean notComplete = true;
private String studId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin_show_student_id);
recycleerviewDetails=(RecyclerView)findViewById(R.id.studentidrecyclerview);
if (recycleerviewDetails != null)
{
recycleerviewDetails.setHasFixedSize(true);
}
layoutManager=new GridLayoutManager(this,1);
recycleerviewDetails.setLayoutManager(layoutManager);
studentidarraylist=new ArrayList<StudentId>();
if(notComplete) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("studAuth");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
for(int i=0;i<objects.size();i++)
{
String studentidstring = (String) objects.get(i).get("StudUserName");
StudentId studentId=new StudentId();
studentId.setStudentId(studentidstring);
studentidarraylist.add(studentId);
}
//Now the arraylist is populated!
for(int i=0;i<studentidarraylist.size();i++)
{
Toast.makeText(AdminShowStudentId.this,studentidarraylist.get(i).getStudentId() + " "+i, Toast.LENGTH_SHORT).show();
}
studentidAdapter=new StudentIdAdapter(studentidarraylist);
recycleerviewDetails.setAdapter(studentidAdapter);
studentidAdapter.notifyDataSetChanged();
recycleerviewDetails.addOnItemTouchListener(new RecyclerViewListener(AdminShowStudentId.this,new RecyclerViewListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
studId=studentidarraylist.get(position).getStudentId();
Intent i=new Intent(AdminShowStudentId.this,ViewStudent.class);
i.putExtra("studId",studId);
startActivity(i);
}
}));
} else {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
notComplete=false;
}
}
}
And It worked!!!
I have made a gallery, in this when i open an image, say image1, in fullview and then swipe in right direction only the image next to image1 i.e image2 comes and the images following image2 are not shown and similar thing happens when i click in reverse direction of image1.
FullimageActivity.java
package com.example.android.helloapp;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.support.v4.view.MotionEventCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.ImageView;
public class Full_ImageActivity extends AppCompatActivity {
float startXValue = 1;
ImageView fullImageView;
int position;
private Integer[] mImageIds = { R.drawable.gallery_one,R.drawable.gallery_two,R.drawable.gallery_three,R.drawable.gallery_four,R.drawable.gallery_five,
R.drawable.gallery_six,R.drawable.gallery_seven,R.drawable.gallery_eight,R.drawable.gallery_nine,R.drawable.gallery_ten,
R.drawable.gallery_eleven,R.drawable.gallery_twelve,R.drawable.gallery_thirteen,R.drawable.gallery_fourteen,R.drawable.gallery_fifteen,
R.drawable.gallery_sixteen,R.drawable.gallery_seventeen,R.drawable.gallery_eighteen,R.drawable.gallery_nineteen,
R.drawable.gallery_twenty,R.drawable.gallery_twenty_one,R.drawable.gallery_twenty_two,R.drawable.gallery_twenty_three,R.drawable.gallery_twenty_four,
R.drawable.gallery_twenty_five};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_PORTRAIT) {
setContentView(R.layout.activity_full__image);
} else {
setContentView(R.layout.activity_full__image);
}
Intent i=getIntent();
position=i.getExtras().getInt("id");
ImageAdapter imageAdapter=new ImageAdapter(this);
fullImageView=(ImageView)findViewById(R.id.fullImageView);
fullImageView.setImageResource(imageAdapter.images[position]);
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int orientation;
if (getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_PORTRAIT) {
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
// or = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}else {
orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
}
// Add code if needed
setRequestedOrientation(orientation);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float endXValue=0;
float x1=event.getAxisValue(MotionEvent.AXIS_X);
int action= MotionEventCompat.getActionMasked(event);
switch (action){
case (MotionEvent.ACTION_DOWN):
startXValue=event.getAxisValue(MotionEvent.AXIS_X);
return true;
case (MotionEvent.ACTION_UP):
endXValue = event.getAxisValue(MotionEvent.AXIS_X);
if (endXValue > startXValue) {
if (endXValue - startXValue > 100) {
System.out.println("Left-Right");
if(position-1!=-1)
fullImageView.setImageResource(mImageIds[position-1]);
}
}else {
if (startXValue -endXValue> 100) {
System.out.println("Right-Left");
if(position+1!=mImageIds.length)
fullImageView.setImageResource(mImageIds[position+1]);
}
}
return true;
default:
return super.onTouchEvent(event);
}
}
}
fullimage.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_full__image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.android.helloapp.Full_ImageActivity">
<include layout="#layout/tool_bar"></include>
<ImageView
android:id="#+id/fullImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:layout_gravity="center"
/>
</LinearLayout>
ImageAdapter.java
package com.example.android.helloapp;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class ImageAdapter extends BaseAdapter {
private Context context;
public Integer[] images={
R.drawable.gallery_one,R.drawable.gallery_two,R.drawable.gallery_three,R.drawable.gallery_four,R.drawable.gallery_five,
R.drawable.gallery_six,R.drawable.gallery_seven,R.drawable.gallery_eight,R.drawable.gallery_nine,R.drawable.gallery_ten,
R.drawable.gallery_eleven,R.drawable.gallery_twelve,R.drawable.gallery_thirteen,R.drawable.gallery_fourteen,R.drawable.gallery_fifteen,
R.drawable.gallery_sixteen,R.drawable.gallery_seventeen,R.drawable.gallery_eighteen,R.drawable.gallery_nineteen,
R.drawable.gallery_twenty,R.drawable.gallery_twenty_one,R.drawable.gallery_twenty_two,R.drawable.gallery_twenty_three,R.drawable.gallery_twenty_four,
R.drawable.gallery_twenty_five
};
public ImageAdapter(Context c){
context=c;
}
#Override
public int getCount() {
return images.length;
}
#Override
public Object getItem(int position) {
return images[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView=new ImageView(context);
imageView.setImageResource(images[position]);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setLayoutParams(new GridView.LayoutParams(240,240));
return imageView;
}
}
once you open any image let's assume position is 3
so go right and display position+1 image but the value of position is still 3 so next time again on swipe position+1 mean 4th image will be displayed
Solution : re-assign the new position value to position variable or use unary operators i.e. position-- or position++
What you're looking for is called ViewPager and it's already implemented in the support library, so you don't have to write all that code by yourself.
References:
https://developer.android.com/reference/android/support/v4/view/ViewPager.html
https://developer.android.com/training/animation/screen-slide.html
I'm having an issue that I have not been able to solve for a couple weeks now. I have an app that adds two EditTexts and one CheckBox on button click. However, whenever I type some content in the EditTexts, and then scroll down, the content disappears when I scroll back up. I cannot figure out a fix for this. I have found a few other very similar posts, however I have tried all solutions I can find, but none have seemed to do the trick for me yet. Here are a couple similar posts I found:
EditText loses content on scroll in ListView
Saving EditText content in RecyclerView
I've recently done some changes to my program in attempt to fix this as well. I added an ArrayList to my MainActivity and passed it to my adapter. I also made two custom text listeners in which onTextChanged, I add the string to the ArrayList. Then, in onBindViewHolder, I update the position in the text listeners, then set the text to the String in the ArrayList at that position. However, this is giving some strange errors. Now, when I add content to an EditText and scroll down, it adds it to multiple EditTexts, and even changes the content in some of them. I'm not sure how to go about fixing this.
Also, on another note, I have the app enabled for drag and drop and swipe to dismiss. So please take that into account as well if you have a solution. Thank you!
MainActivity
import android.content.ClipData;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ArrayList<ListItems> itemsList;
private RecyclerView mRecyclerView;
private MyRecyclerAdapter adapter;
private List<String> courseStrings = new ArrayList<>();
private List<String> creditStrings = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
courseStrings.add("");
creditStrings.add("");
// Toast variable in order to fix toast queueing issue.
final Toast toast = Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT);
// For the recycler view.
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
itemsList = new ArrayList<>();
adapter = new MyRecyclerAdapter(MainActivity.this, itemsList, courseStrings, creditStrings);
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(linearLayoutManager);
// For the addCourse button.
final Button addCourse = (Button) findViewById(R.id.addCourse);
addCourse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
adapter.createListItem(new ListItems(null, null, false), toast);
toast.setText("New course added");
toast.show();
}
});
final Button clearAll = (Button) findViewById(R.id.clearAll);
clearAll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// In order to clear the list.
if (itemsList.size() == 0) {
toast.setText("All courses have already been cleared.");
toast.show();
} else {
adapter.clearAdapter();
toast.setText("All courses have been cleared.");
toast.show();
}
}
});
// For the drag and drop/swipe to dismiss.
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(
new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN,
ItemTouchHelper.LEFT) {
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
final int fromPos = viewHolder.getAdapterPosition();
final int toPos = target.getAdapterPosition();
Collections.swap(itemsList, fromPos, toPos);
adapter.notifyItemMoved(fromPos, toPos);
return true;
}
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
adapter.onItemDismiss(viewHolder.getAdapterPosition());
}
});
itemTouchHelper.attachToRecyclerView(mRecyclerView);
} // End of onCreate
} // End of MainActivity
MyRecyclerAdapter
import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.view.LayoutInflater;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.CustomRowViewHolder> {
private ArrayList<ListItems> itemsList;
private Context mContext;
private List<String> courseStrings;
private List<String> creditStrings;
public MyRecyclerAdapter(Context context, ArrayList<ListItems> itemsList, List<String> courseStrings, List<String> creditStrings){
this.itemsList = itemsList;
this.mContext = context;
this.courseStrings = courseStrings;
this.creditStrings = creditStrings;
}
#Override
public MyRecyclerAdapter.CustomRowViewHolder onCreateViewHolder(final ViewGroup viewGroup, int position) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.new_course_row, null);
final CustomRowViewHolder holder = new CustomRowViewHolder(v, new CoursesCustomTextListener(), new CreditsCustomTextListener());
holder.creditsText.setInputType(InputType.TYPE_CLASS_NUMBER);
holder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.checkBox.isChecked()) {
holder.courseText.setEnabled(false);
holder.courseText.setFocusable(false);
holder.courseText.setInputType(InputType.TYPE_NULL);
holder.creditsText.setEnabled(false);
holder.creditsText.setFocusable(false);
holder.creditsText.setInputType(InputType.TYPE_NULL);
} else {
holder.courseText.setEnabled(true);
holder.courseText.setFocusable(true);
holder.courseText.setFocusableInTouchMode(true);
holder.courseText.setInputType(InputType.TYPE_CLASS_TEXT);
holder.creditsText.setEnabled(true);
holder.creditsText.setFocusable(true);
holder.creditsText.setFocusableInTouchMode(true);
holder.creditsText.setInputType(InputType.TYPE_CLASS_NUMBER);
} // End if else
}
});
return holder;
} // End of onCreateViewHolder
#Override
public void onBindViewHolder(CustomRowViewHolder holder, final int position) {
ListItems listItem = itemsList.get(position);
int focusedItem = 0;
holder.itemView.setSelected(focusedItem == position);
holder.getLayoutPosition();
holder.creditsCustomTextListener.updatePosition(position);
holder.creditsCustomTextListener.updatePosition(position);
holder.courseText.setText(courseStrings.get(position));
holder.creditsText.setText(creditStrings.get(position));
// Set listener to check box.
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
itemsList.get(position).setIsComplete(b);
}
});
holder.checkBox.setChecked( itemsList.get(position).getIsComplete());
} // End of onBindViewHolder
public void clearAdapter() {
itemsList.clear();
notifyDataSetChanged();
} // End of clearAdapter
public int getItemCount() {
return(null != itemsList ? itemsList.size() : 0);
} // End of getItemCount
public void onItemDismiss(int position) {
itemsList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, itemsList.size());
} // End of onItemDismiss
public void createListItem(ListItems listItem, Toast toast) {
itemsList.add(listItem);
int position = itemsList.indexOf(listItem);
notifyItemInserted(position);
} // End of createListItem
///////////////////////////////////// CustomRowViewHolder /////////////////////////////////////
public static class CustomRowViewHolder extends RecyclerView.ViewHolder {
public EditText courseText;
public EditText creditsText;
public CheckBox checkBox;
public RelativeLayout relativeLayout;
public CoursesCustomTextListener coursesCustomTextListener;
public CreditsCustomTextListener creditsCustomTextListener;
public CustomRowViewHolder(View view, CoursesCustomTextListener coursesCustomTextListener, CreditsCustomTextListener creditsCustomTextListener) {
super(view);
this.coursesCustomTextListener = coursesCustomTextListener;
this.creditsCustomTextListener = creditsCustomTextListener;
this.courseText = (EditText) view.findViewById(R.id.course);
this.creditsText = (EditText) view.findViewById(R.id.credits);
this.checkBox = (CheckBox) view.findViewById(R.id.complete);
this.relativeLayout = (RelativeLayout) view.findViewById(R.id.relLayout);
this.courseText.addTextChangedListener(coursesCustomTextListener);
this.creditsText.addTextChangedListener(creditsCustomTextListener);
}
}
////////////////////////////////// CoursesCustomTextListener //////////////////////////////////
private class CoursesCustomTextListener implements TextWatcher {
private int position;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// No operation to perform.
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
courseStrings.add(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
// No operation to perform.
}
}
////////////////////////////////// CreditsCustomTextListener //////////////////////////////////
private class CreditsCustomTextListener implements TextWatcher {
private int position;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// No operation to perform.
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
creditStrings.add(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
// No operation to perform.
}
}
} // End of MyRecyclerAdapter
ListItems
import java.util.ArrayList;
public class ListItems {
private String course;
private String credits;
private Boolean complete;
public ListItems(String mCourse, String mCredits, Boolean mComplete) {
course = mCourse;
credits = mCredits;
complete = mComplete;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public String getCredits() {
return credits;
}
public void setCredits(String credits) {
this.credits = credits;
}
public Boolean getIsComplete() {
return complete;
}
public void setIsComplete(Boolean complete) {
this.complete = complete;
}
} // End of ListItems
new_course_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/relLayout"
android:layout_margin="5dp">
<EditText
android:layout_width="130dp"
android:layout_height="wrap_content"
android:id="#+id/course"
android:hint="Enter Course ID"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="16sp"
android:maxLines="1" />
<EditText
android:layout_width="115dp"
android:layout_height="wrap_content"
android:id="#+id/credits"
android:hint="Enter Credits"
android:layout_alignBottom="#+id/course"
android:textSize="16sp"
android:layout_toRightOf="#+id/course"
android:maxLines="1" />
<CheckBox
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Check if complete"
android:id="#+id/complete"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignBottom="#+id/course"
android:textSize="13sp"
android:paddingBottom="4dp"
android:paddingTop="4dp" />
</RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="#+id/rl"
tools:context=".MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add Course"
android:id="#+id/addCourse"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:textColor="#FFF"
android:background="#drawable/my_button"
android:textSize="18dp"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear All"
android:id="#+id/clearAll"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:textColor="#FFF"
android:background="#drawable/my_button"
android:textSize="18dp"
android:paddingRight="5dp"
android:paddingLeft="5dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"/>
<android.support.v7.widget.RecyclerView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/recycler_view"
android:layout_below="#+id/addCourse"
android:layout_marginTop="10dp"
/>
</RelativeLayout>
Thank you in advance for any help! I could REALLY use a solution!
EDIT: I've noticed now that, say I enter "aaaaaaa" in the first EditText, then it will add "a" to an EditText further down the list, then "aa" to the EditText after that one, then "aaa", "aaaa", until it reaches "aaaaaaa". Then there will be a few empty EditText's, and then it will start it over again. Here is a visual:
EDIT x2: Haven't worked on this in a while, and haven't been getting any answers. Even got the "Tumbleweed" badge for this post! Anyone have any ideas?
Though I am not quite sure but I believe this is happening because recycler view regenerates its positons . For your custom edit text you are adding the string ` #Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
courseStrings.add(s.toString());
}
for both edit texts.
In recyler view you have implemented this.courseText.addTextChangedListener(coursesCustomTextListener);
so everytime you scroll the onBind Method is called and as the position changes this must be getting called too. Hence it must be regenerating . I request you to first try
holder.courseText.setTag(position);
in onBindViewHolder().
Try it for both texts individually.If it does work then try
holder.view.setTag(position);
I've looked through a few posts, but can't get the checkbox to acknowledge clicks. I think I'm 90% there but falling over the last hurdle.
I have a ListFragment where each item has a CheckBox and a TextView. When users click on the TextView they're taken to a new fragment. But when they click the CheckBox I want the value to be ticked/unticked directly in the list.
Here's my code, kept it so that only classes relevant to the ListView are shown, let me know if you need to see others.
I did follow this guide but can't really understand why it's not working on my code: http://www.mysamplecode.com/2012/07/android-listview-checkbox-example.html
TaskListFragment.java
package com.laytonlabs.android.todotoday;
import java.util.ArrayList;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.TextView;
public class TaskListFragment extends ListFragment {
ArrayList<Task> mTasks;
private boolean mSubtitleVisible;
private Callbacks mCallbacks;
private static final String TAG = "TaskListFragment";
private int touchPositionX;
public interface Callbacks {
void onTaskSelected(Task task);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallbacks = (Callbacks)activity;
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
getActivity().setTitle(R.string.crimes_title);
mTasks = TaskLab.get(getActivity()).getTasks();
TaskAdapter adapter = new TaskAdapter(mTasks);
setListAdapter(adapter);
setRetainInstance(true);
mSubtitleVisible = false;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_crime_list, menu);
MenuItem showSubtitle = menu.findItem(R.id.menu_item_show_subtitle);
if (mSubtitleVisible && showSubtitle != null) {
showSubtitle.setTitle(R.string.hide_subtitle);
}
}
#TargetApi(11)
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_new_crime:
Task task = new Task();
TaskLab.get(getActivity()).addTaskToFirst(task);
((TaskAdapter)getListAdapter()).notifyDataSetChanged();
mCallbacks.onTaskSelected(task);
return true;
case R.id.menu_item_show_subtitle:
if (getActivity().getActionBar().getSubtitle() == null) {
getActivity().getActionBar().setSubtitle(R.string.subtitle);
mSubtitleVisible = true;
item.setTitle(R.string.hide_subtitle);
} else {
getActivity().getActionBar().setSubtitle(null);
mSubtitleVisible = false;
item.setTitle(R.string.show_subtitle);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.crime_list_item_context, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
int position = info.position;
TaskAdapter adapter = (TaskAdapter)getListAdapter();
Task task = adapter.getItem(position);
switch (item.getItemId()) {
case R.id.menu_item_delete_crime:
TaskLab.get(getActivity()).deleteTask(task);
adapter.notifyDataSetChanged();
return true;
}
return super.onContextItemSelected(item);
}
#TargetApi(11)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = super.onCreateView(inflater, parent, savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (mSubtitleVisible) {
getActivity().getActionBar().setSubtitle(R.string.subtitle);
}
}
ListView listView = (ListView)v.findViewById(android.R.id.list);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
//Use floating context menus on Froyo and Gingerbread
registerForContextMenu(listView);
} else {
//Use contextual action bar on Honeycomb and higher
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.crime_list_item_context, menu);
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_delete_crime:
TaskAdapter adapter = (TaskAdapter)getListAdapter();
TaskLab taskLab = TaskLab.get(getActivity());
for (int i = adapter.getCount() - 1; i >= 0; i--) {
if (getListView().isItemChecked(i)) {
taskLab.deleteTask(adapter.getItem(i));
}
}
mode.finish();
adapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// TODO Auto-generated method stub
}
});
}
return v;
}
#Override
public void onResume() {
super.onResume();
((TaskAdapter)getListAdapter()).notifyDataSetChanged();
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Task t = ((TaskAdapter)getListAdapter()).getItem(position);
mCallbacks.onTaskSelected(t);
}
private class TaskAdapter extends ArrayAdapter<Task> {
public TaskAdapter(ArrayList<Task> tasks) {
super(getActivity(), 0, tasks);
}
private class ViewHolder {
TextView titleTextView;
CheckBox completedCheckBox;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
//If we wern't given a view, inflate one
if (convertView == null) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_task, null);
holder = new ViewHolder();
holder.titleTextView = (TextView)convertView.findViewById(R.id.task_list_item_titleTextView);
holder.completedCheckBox = (CheckBox)convertView.findViewById(R.id.task_list_item_completedCheckBox);
convertView.setTag(holder);
holder.completedCheckBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Task task = (Task) cb.getTag();
task.setCompleted(cb.isChecked());
Log.d(TAG, "Clicked on checkbox for: " + task.getmTitle());
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
//Configure the view for this Task
Task t = getItem(position);
holder.titleTextView.setText(t.getmTitle());
holder.completedCheckBox.setChecked(t.isCompleted());
holder.completedCheckBox.setTag(t);
return convertView;
}
}
public void updateUI() {
((TaskAdapter)getListAdapter()).notifyDataSetChanged();
}
}
list_item_task.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox
android:id="#+id/task_list_item_completedCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:enabled="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="4dp" />
<TextView
android:id="#+id/task_list_item_titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:text="Task title" />
</LinearLayout>
Thanks in Advance!
Your clicks are not getting thru, because ur CheckBox has
android:enabled="false"
Which prevents the onClickListener from firing.
Remove this line, and try again.
Also, I advise you to change width of TextView to wrap_content, and rather position the CheckBox to the right.
In your list_item_task.xml layout file, where the CheckBox and TextView are defined, you set to the TextView
android:layout_width="match_parent"
when it should be as in the tutorial
android:layout_width="wrap_content"
It is possible that the too wide text is intercepting the click event from the checkbox.
Hi I'm trying to insert a Button into anEmptyView. The only thing I can seem to get to work is the EmptyText where a text value is displayed when the list is empty. This code works for just displaying a textview. How can I successfully add a button to the view?
import java.util.ArrayList;
import android.annotation.TargetApi;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.text.format.DateFormat;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.robertrichardson.crimeproofassistant.R.string;
public class crimeListFragment extends ListFragment {
private ArrayList<crime> mcrime;
private boolean mSubtitleVisible;
public static final String TAG = "crimeListFragment";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
getActivity().setTitle(R.string.app_name);
mcrime = crimeLab.get(getActivity()).getcrime();
crimeAdapter adapter = new crimeAdapter(mcrime);
setListAdapter(adapter);
setRetainInstance(true);
mSubtitleVisible = false;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setEmptyText(getResources().getString(string.new_crime_attack_empty_desc));
registerForContextMenu(getListView());
setHasOptionsMenu(true);
}
#TargetApi(11)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
View v = super.onCreateView(inflater, parent, savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (mSubtitleVisible) {
getActivity().getActionBar().setSubtitle(R.string.subtitle);
}
}
ListView listView = (ListView)v.findViewById(android.R.id.list);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
// Use floating point context menus on Froyer and Gingerbread
registerForContextMenu(listView);
} else {
// Use contextual action bar on Honeycomb and higher
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
// ActionMode.Callback methods
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.crime_list_item_context, menu);
return true;
}
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// required but not used in this implementation
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_delete_crime:
crimeAdapter adapter = (crimeAdapter)getListAdapter();
crimeLab crimeLab = crimeLab.get(getActivity());
for (int i = adapter.getCount() - 1; i >= 0; i--) {
if (getListView().isItemChecked(i)) {
crimeLab.deletecrime(adapter.getItem(i));
}
}
mode.finish();
adapter.notifyDataSetChanged();
return true;
default:
return false;
}
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
// Required, but not used in this implementation
}
public void onDestroyActionMode(ActionMode mode) {
}
});
}
return v;
}
public void onListItemClick(ListView l, View v, int position, long id) {
crime c = ((crimeAdapter)getListAdapter()).getItem(position);
// Start crime Activity
Intent i = new Intent(getActivity(), crimePagerActivity.class);
i.putExtra(crimeFragment.EXTRA_crime_ID, c.getId());
startActivity(i);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
((crimeAdapter)getListAdapter()).notifyDataSetChanged();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_crime_list, menu);
MenuItem showSubtitle = menu.findItem(R.id.menu_item_show_subtitle);
if (mSubtitleVisible && showSubtitle != null) {
showSubtitle.setTitle(R.string.hide_subtitle);
}
}
#TargetApi(11)
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_new_crime:
crime crime = new crime();
crimeLab.get(getActivity()).addcrime(crime);
Intent i = new Intent(getActivity(), crimePagerActivity.class);
i.putExtra(crimeFragment.EXTRA_crime_ID, crime.getId());
startActivityForResult(i,0);
return true;
case R.id.menu_item_show_subtitle:
if (getActivity().getActionBar().getSubtitle() != null) {
getActivity().getActionBar().setSubtitle(R.string.subtitle);
mSubtitleVisible = true;
item.setTitle(R.string.hide_subtitle);
} else {
getActivity().getActionBar().setSubtitle(null);
mSubtitleVisible = false;
item.setTitle(R.string.show_subtitle);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateContextMenu(ContextMenu menu,View v, ContextMenuInfo menuInfo) {
getActivity().getMenuInflater().inflate(R.menu.crime_list_item_context, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
int position = info.position;
crimeAdapter adapter = (crimeAdapter)getListAdapter();
crime crime = adapter.getItem(position);
switch (item.getItemId()) {
case R.id.menu_item_delete_crime:
crimeLab.get(getActivity()).deletecrime(crime);
adapter.notifyDataSetChanged();
return true;
}
return super.onContextItemSelected(item);
}
private class crimeAdapter extends ArrayAdapter<crime> {
public crimeAdapter(ArrayList<crime> crime) {
super(getActivity(), 0, crime);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// If we weren't given a view, inflate one
if (convertView == null) {
convertView = getActivity().getLayoutInflater()
.inflate(R.layout.list_item_crime, null);
}
// Enter the view of this crime Attack
crime c = getItem(position);
TextView titleTextView =
(TextView)convertView.findViewById(R.id.crime_list_item_titleTextView);
titleTextView.setText(c.getTitle());
TextView dateTextView =
(TextView)convertView.findViewById(R.id.crime_list_item_dateTextView);
dateTextView.setText(DateFormat.format("EEEE, MMM dd, yyyy hh : mm a", c.getDate()).toString());
CheckBox resolvedCheckBox =
(CheckBox)convertView.findViewById(R.id.crime_list_item_resolvedCheckBox);
resolvedCheckBox.setChecked(c.isResolved());
return convertView;
}
}
#Override
public void onResume() {
super.onResume();
((crimeAdapter)getListAdapter()).notifyDataSetChanged();
}
}
Here's my XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#f2f3f4"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="#android:id/list"
android:background="#f2f3f4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</ListView>
<linearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f2f3f4"
android:orientation="vertical"
>
<TextView
android:id="#android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:text="#string/new__empty_desc"
/>
<Button
android:id="#+id/addButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:text="#string/new_attack_empty"
/>
</linearLayout>
</FrameLayout>
public class MainActivity extends Activity {
private CustomBaseAdapter customBaseAdapter;
private ListView lv;
private Button btn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout fl = new FrameLayout(this);
btn = new Button(this);
btn.setText("Hit me");
lv = new ListView(this);
customBaseAdapter = new CustomBaseAdapter(this);
lv.setAdapter(customBaseAdapter);
fl.addView(lv);
fl.addView(btn);
setContentView(fl);
handleVisbility();
}
public void handleVisbility() {
if (customBaseAdapter.getCount() == 0) {
lv.setVisibility(View.GONE);
btn.setVisibility(View.VISIBLE);
} else {
lv.setVisibility(View.VISIBLE);
btn.setVisibility(View.GONE);
}
}
public class CustomBaseAdapter extends BaseAdapter {
private Context context;
View superView;
public CustomBaseAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return 1;
}
#Override
public Object getItem(int arg0) {
return new Object();
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
FrameLayout fl = new FrameLayout(context);
Button btn = new Button(context);
btn.setText("Hello, im a Button");
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Yay hit me again", Toast.LENGTH_LONG).show();
}
});
fl.addView(btn);
return fl;
}
}
}
Ok, this is kinda what you want to do here. It shows a ListView, if there is an Item in the List, and will show the Button if the List is Empty. Only thing you have to do, is to call handleVisbility() everytime you make a change to the ListViews content. Especially after you add something to the List.
The default implementation of the ListFragment involves setting up a textView as the empty view for the list.
http://developer.android.com/reference/android/app/ListFragment.html#setEmptyText(java.lang.CharSequence)
You can change this by extending a Fragment and create your own ListView inside it. you can use the code from the ListFragment if you like some of the things it offers.
As an alternative you can try to do getListView().setEmptyView() and set up the view that you need. Again see how they do it in the code in the ListFragment and reproduce it with a different View (instead of TextView use a Button or ImageButton whatever you need)
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/ListFragment.java