SearchView retrieving wrong data with List View - android-studio

When searching for an item, I'm able to retrieve the Title, Artist, and Image for the respective Songs. However, the first 2 items displayed in the ListView when clicked on keeps returning the last song in my list instead of the correct song that is being displayed.
E.g, When clicking on "Life is Good" or "Good as hell", the song "First Time" will be displayed instead. However "Perfect", "Lemon", and "Autopilot" are working fine. These are the only codes used to search! SearchByTitle and GetTitle() are taken from the files where the songs are hardcoded in!
My Activity:
ListView listView;
ArrayList<String> stringArrayList = new ArrayList<>();
ArrayAdapter<String> adapter;
private SongCollection songCollection = new SongCollection();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
listView = findViewById(R.id.list_view);
stringArrayList.add("Life is Good");
stringArrayList.add("Good As Hell");
stringArrayList.add("Perfect");
stringArrayList.add("Lemon");
stringArrayList.add("Autopilot");
stringArrayList.add("First Time");
adapter = new ArrayAdapter<>(SearchActivity.this, android.R.layout.simple_list_item_1, stringArrayList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(),
adapter.getItem(i), Toast.LENGTH_SHORT).show();
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String value = listView.getItemAtPosition(i).toString();
Song selectedSong = songCollection.searchByTitle(value);
AppUtil.popMessage(view.getContext(), "Streaming song: " + selectedSong.getTitle());
sendDataToActivity(selectedSong);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.my_menu, menu);
MenuItem menuItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
}
XML to my Activity:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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"
android:background="#404040"
tools:context=".SearchActivity">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#404040">
<ListView
android:id="#+id/list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#FFFFFF"
android:divider="#color/white"
android:dividerHeight="2dp"
tools:listitem="#android:layout/simple_list_item_1">
</ListView>
</LinearLayout>
</RelativeLayout>

It happens because you need to create a new list which would contain the search results, you don't have to do the search operation with your original list which isstringArrayList
Instead create a new list which is mylist in this case, and store the search results and call that list in onQueryTextChange
Create this method, I modified the code according to your code
private void search(String str) {
ArrayList<String> myList = new ArrayList<>();
for (Quote object : stringArrayList) {
if (object.GetTitle().toLowerCase().contains(str.toLowerCase())) {
myList.add(object);
}
}
AdapterClass adapterClass = new AdapterClass(this, myList);//, swiper
recyclerView.setAdapter(adapterClass);
}
Now, call this method under search setOnQueryTextListener, like this
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
search(newText);
return true;
}
});
OPTIONAL
And one more modification which you can do is you can check setOnQueryTextListener when ever there is some text in it, like this
if (searchView != null) {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
search(s);
return true;
}
});
}
If my answer solves your problem you can give me an up-vote and mark my answer as correct, by clicking on the gray tick button beside the starting of my answer, which will then turn green!

Related

I have to apply autocomplete inside home fragment in bottom nav menu but I am unable to type anything in search tab

I have to apply autocomplete inside home fragment in bottom nav menu but I am unable to type anything in search tab.
I am getting this interface but when I try to enter anything in the search tab it doesn't take any input as if it don't even open the keyboard:
My JavaScript code for homefragment is as follows:
public class HomeFragment extends Fragment implements OnMapReadyCallback {
private HomeViewModel homeViewModel;
FragmentHomeBinding binding;
private GoogleMap mMap;
private FusedLocationProviderClient fusedLocationProviderClient;
private LocationRequest locationRequest;
private LocationCallback locationCallback;
private Marker marker;
private MarkerOptions markerOptions;
SupportMapFragment mapFragment;
#Override
public void onDestroy() {
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
super.onDestroy();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
binding = FragmentHomeBinding.inflate(inflater, container, false);
homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
init();
return binding.getRoot();
}
private void setupAutoCompleteFragment()
{
SupportPlaceAutocompleteFragment autocompleteFragment = (SupportPlaceAutocompleteFragment) getChildFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
}
#Override
public void onError(Status status) {
Log.e("Error", status.getStatusMessage());
}
});
}
#SuppressLint("MissingPermission")
private void init() {
locationRequest = new LocationRequest();
locationRequest.setSmallestDisplacement(10f);
locationRequest.setInterval(3000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setFastestInterval(1500);
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
LatLng newPosition = new LatLng(locationResult.getLastLocation().getLatitude(), locationResult.getLastLocation().getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(newPosition, 18f));
}
;
};
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getContext());
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
}
private void gotoLatLng(double latitude, double longitude, float v) {
LatLng latLng = new LatLng(latitude, longitude);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(latLng,18f);
mMap.animateCamera(update);
}
#Override
public void onMapReady(#NonNull GoogleMap googleMap) {
mMap = googleMap;
Dexter.withContext(getContext()).
withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new PermissionListener() {
#SuppressLint("MissingPermission")
#Override
public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.setOnMyLocationButtonClickListener(() -> {
fusedLocationProviderClient.getLastLocation().addOnFailureListener(e -> Toast.makeText(getContext(), "" + e.getMessage(), Toast.LENGTH_SHORT).show())
.addOnSuccessListener(location -> {
LatLng userLatLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(userLatLng, 21f));
});
return true;
});
View locationButton = ((View)mapFragment.getView().findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,RelativeLayout.TRUE);
params.setMargins(0,0,0,50);
}
#Override
public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {
Toast.makeText(getContext(), "Permission" + permissionDeniedResponse.getPermissionName() + "" + "was denied !", Toast.LENGTH_SHORT).show();
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
permissionToken.continuePermissionRequest();
}
}).check();
}
}
And the layout used is for same fragment is as follows:
<?xml version="1.0" encoding="UTF-8" ?>
<FrameLayout 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=".ui.home.HomeFragment">
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity"
android:layout_gravity="center_horizontal|bottom" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/backcolor">
<fragment
android:id="#+id/place_autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter Place"
android:background="#fff"
android:name="com.google.android.gms.location.places.ui.SupportPlaceAutocompleteFragment"
/>
</androidx.cardview.widget.CardView>
</FrameLayout>

Android Studio, Capture FrameLayout View, While Camera is StopPreview()

This is my CameraView.java (I got it from http://blog.rhesoft.com/)
public class CameraView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraView(Context context, Camera camera){
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try{
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
if(mHolder.getSurface() == null)
return;
try{
mCamera.stopPreview();
} catch (Exception e){
}
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.stopPreview();
mCamera.release();
}}
and this is my MainActivity.java.
public class MainActivity extends AppCompatActivity {
private Camera mCamera = null;
private CameraView mCameraView = null;
private FrameLayout camera_view;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try{
mCamera = Camera.open();
//you can use open(int) to use different cameras
} catch (Exception e){
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if(mCamera != null) {
mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
camera_view = (FrameLayout)findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
//btn to close the application
final ImageButton imgClose = (ImageButton)findViewById(R.id.imgClose);
final ImageButton capImg = (ImageButton) findViewById(R.id.imgCapture);
imgClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
imgClose.setVisibility(View.INVISIBLE);
capImg.setVisibility(View.VISIBLE);
mCamera.startPreview();
}
});
capImg.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
mCamera.stopPreview();
imgClose.setVisibility(View.VISIBLE);
capImg.setVisibility(View.INVISIBLE);
}
});
}
#Override
public void onBackPressed(){
System.exit(0);
}}
and this my activity_main.xml.
<FrameLayout
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=".MainActivity">
<FrameLayout
android:id="#+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgClose"
android:layout_gravity="right|top"
android:background="#android:drawable/ic_menu_close_clear_cancel"
android:padding="20dp"
android:visibility="invisible" />
<ImageButton
android:layout_width="98dp"
android:layout_height="98dp"
android:id="#+id/imgCapture"
android:layout_gravity="center_horizontal|bottom"
android:background="#android:drawable/ic_menu_camera"
android:padding="20dp"/>
Can I capture this FrameLayout preview as image or do some programing with that preview like delete red color? Can you give me some clue?
So if I understand correctly, you wish to get the image data that is shown when you stop the preview? If you so you can mCamera.takePicture() method. It takes 3 parameters, all of which are useful callbacks. Here is something I recently did to show you.
btn_Capture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mCamera == null)
return;
mCamera.takePicture(null, null, mPicture);
}
});
This is my button click listener which is a floating image button (any button will work just fine). The third parameter is a callback that returns an array of pixels that you can convert into a bitmap.
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
mCamera.stopPreview();
Bitmap bMap = BitmapFactory.decodeByteArray(data, 0, data.length);
preview.removeView(mPreview);
img_Captured.setImageBitmap(bMap);
}
};
This is the callback which I passed in the takePicture() method. byte[] data is the image that you are trying to get. As you can see I converted it into a bitmap and displayed it to an ImageView after removing the surfaceview (which holds the camera preview). Just a note, the takePicture() method stops the preview automatically so don't stop the preview before taking the photo. You can do it how I did it in the callback. Also, if you want to take another photo, you can start the preview again.
I hope this helps!! Let me know if I left anything out! By the way, it is all documented on the Android Developer site.
http://developer.android.com/training/camera/cameradirect.html#TaskTakePicture

Converting listview to ListView with custom rows

I am trying to convert my basic list view into a complex list view. I tried doing this by creating a product adapter. I keep getting an error on the super part saying "objects() in objects cannot be applied". I have not done this before, I was following a tutorial.
public class ProductAdapter {
ProductAdapter(Context context, String[] addProduct){
super(context,R.layout.list_item, addProduct);
}
#Override
public View getView(int position,View convertView, ViewGroup parent){
LayoutInflater momentsInflater = LayoutInflater.from(getContext());
View customView = momentsInflater.inflate(R.layout.list_item, parent, false);
ImageView imageView = (ImageView) customView.findViewById(R.id.imageView);
TextView momentsText = (TextView) customView.findViewById(R.id.textViewName);
ImageView momentsImage = (ImageView) customView.findViewById(R.id.imageView);
}
};
MainActivity
public class MainActivity extends Activity {
private ListView listView;
private String[] details;
public static ArrayList<Product> product = new ArrayList<>();
boolean firstRun = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_AddProduct:
startActivity(new Intent(MainActivity.this, Activity_addProduct.class));
case R.id.action_Information:
startActivity(new Intent(MainActivity.this, Activity_addProduct.class));
return true;
case R.id.action_Home:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onResume() {
super.onResume();
DatabaseHandler db = new DatabaseHandler(this);
String[] productStrings;
if (firstRun) {
String[] placeHolterStrings = {"", ""};
productStrings = placeHolterStrings;
firstRun = false;
} else {
product = db.getAllContacts();
productStrings = new String [product.size()];
for (int i = 0; i < product.size(); i++) {
productStrings[i] = product.get(i).toString();
}
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, productStrings);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
);
}
}
Myproduct class
public class Product {
private int id;
private String productName;
private String productModel;
public Product(int id, String productName, String productModel) {
this.id = id;
this.productName = productName;
this.productModel = productModel;
}
public Product() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setName(String productName) {
this.productName = productName;
}
public String getProductModel() {
return productModel;
}
public void setProductModel(String productModel) {
this.productModel = productModel;
}
#Override
public String toString() {
return this.productName + " " + this.productModel;
}
}
List_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageView"
android:layout_width="85dp"
android:layout_height="85dp"
android:background="#android:color/darker_gray"
android:padding="8dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="20dp"
android:orientation="vertical">
<TextView
android:id="#+id/textViewName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="first + last name"
android:textSize="16dp" />
<TextView
android:id="#+id/textViewDetail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="details of the candidate"
android:textSize="12dp" />
</LinearLayout>
</LinearLayout>
A complex list view is the example below:

ListView with custom view as item only shows one element

I have an AlertDialog that I inflate from this layout:
<?xml version="1.0" encoding="utf-8"?>
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/List"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="400dp"/>
I need every item of the list to be a view described by this
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:background="#20f0f0f0"
android:orientation="horizontal" >
<CheckBox
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:id="#+id/cb_persistent"/>
<TextView
style="#style/Label"
android:layout_gravity="center_vertical"
android:gravity="center_horizontal|center_vertical"
android:layout_width="fill_parent"
android:layout_height="#dimen/button_height"
android:layout_toLeftOf="#+id/btn_connect"
android:layout_toRightOf="#+id/cb_persistent"
android:id="#+id/lbl_name_address"/>
<Button
android:layout_gravity="center_vertical"
style="#style/Button.Plain"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:id="#+id/btn_connect"
android:text="#string/Connect"/>
</RelativeLayout>
And this is the adapter I'm trying to use for it. I've also tried implementing ListAdapter, result was the same: only 1 list row is showing, the dialog is exactly 1 row high. With this adapter it's the last row, with ListAdapter - the first. What am I doing wrong?
private class ListItem extends View {
public ListItem(Context context) {
super(context);
View content = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.list_element, null);
setView(content);
m_cbPersistent = (CheckBox) content.findViewById(R.id.cb_persistent);
m_btnConnect = (Button) content.findViewById(R.id.btn_connect);
m_lblName = (TextView) content.findViewById(R.id.lbl_name_address);
}
public CheckBox m_cbPersistent = null;
public Button m_btnConnect = null;
public TextView m_lblName = null;
}
class NewAdapter extends ArrayAdapter<ListItem>
{
public NewAdapter(Context context) {
super(context, 0);
m_context = context;
}
#Override
public int getCount() {
return m_items.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (position < getCount())
return m_items.elementAt(position);
else
return null;
}
void addNewItem ()
{
m_items.add(new NetworkCameraEntry(m_context));
}
void removeItem (int index)
{
if (index < getCount())
{
m_items.remove(index);
}
}
#Override
public boolean isEmpty() {
return m_items.size() <= 0;
}
#Override
public boolean areAllItemsEnabled() {
return true;
}
#Override
public boolean isEnabled(int position) {
return true;
}
private Context m_context = null;
private Vector<ListItem> m_items = new Vector<ListItem>();
}
This is how I initialize it in the AlertDialog's constructor:
public class MyDialog extends AlertDialog {
public MyDialog(Context context) {
super(context, 0);
View content = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.network_cameras_list_window, null);
setView(content);
m_adapter = new NewAdapter(context);
m_list = (ListView) content.findViewById(R.id.List);
m_list.setAdapter(m_adapter);
m_adapter.addNewItem();
m_adapter.addNewItem();
}
private ListView m_list = null;
private NewAdapter m_adapter = null;
}
m_items.size is 1 when the adapter is constructed and gets populated over time.
m_items.size is cached so you have to invalidate the adapter on each m_items.add
Yet this is not the way to go. A better option is to get your data populated before constructing the adapter and pass is to the adapter. Any altering of the data you have to notify / invalidate the adapter with
notifyDataSetInvalidated();
notifyDataSetChanged();

How to add a widget to a ListView to scroll with items, but also be visible when the ListView's adapter is empty

I have a ListView and a widget. I want the widget to be always on the top of ListView, and it should be able to scroll with the items but when there is no items in adapter it should still be visible. This is how it doesn't scroll:
The layout file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="#+id/btn_togle_empty"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="toggle empty"
/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ListView
android:id="#+id/list_test"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<ViewStub
android:id="#+id/empty_layout"
android:layout="#layout/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</FrameLayout>
</LinearLayout>
The code for the activity:
public class MyActivity extends Activity {
private MyAdapter adapter;
private ListView v;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
v = (ListView) findViewById(R.id.list_test);
View empty = findViewById(R.id.empty_layout);
v.setEmptyView(empty);
final MyAdapter adapter = new MyAdapter();
v.setAdapter(adapter);
Button btn = (Button) findViewById(R.id.btn_togle_empty);
btn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
adapter.togleEmpty();
}
});
}
private class MyAdapter extends BaseAdapter {
boolean empty = false;
#Override
public int getCount() {
return empty ? 0 : 50;
}
#Override
public Object getItem(int i) {
return new Object();
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
TextView v = new TextView(MyActivity.this);
v.setText("STRING");
return v;
}
public void togleEmpty() {
empty = !empty;
notifyDataSetChanged();
}
}
}
I had one more idea, add the widget as header, but it disappears when the ListView is empty. How can I achieve the result I want?
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (i == 0) { return custom_widget_view; }
}

Resources