How to retain progress bar state while switching the fragments? - android

I have a navigation drawer where these many options are present
Image material
Video Material
Audio Material
We are maintaining separate fragment for each material and every fragment have grid view in which we are populating thumbnail of that material. Once user click on the thumbnail a full material will be downloaded(Using AsyncTask). I am displaying the progress bar over the thumbnail while downloading the full material.
Now here i stuck to a problem that suppose progress bar is showing 20% and i switched the fragment to another and again came back to the same and the downloading progress bar is lost.
I went to a solution to use intent service and broadcast receiver to populate the progress bar but in that case on every added bytes a broadcasting will be done is it a good practice ?

The previous answer wasn't good enough, I made up a new one, have a look, it works very well.
The code consists of the Base Class for fragments, Two fragments, Model for holding data for grid elements and Main UI thread.
The base class:
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by Movsar Bekaev on 20/09/2015.
*/
public class GridFragment extends Fragment {
static ArrayList<xThumbnail> myInformation;
static Activity mActivity;
GAdapter adapter;
GridView grid;
enum fragment_names {FR1, FR2}
static fragment_names this_fragment_name;
public GridFragment() {
refresh();
}
protected void refresh() {
if (grid == null) {
grid = new GridView(mActivity);
grid.setLayoutParams(new GridView.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
grid.setBackgroundColor(Color.WHITE);
grid.setNumColumns(2);
grid.setColumnWidth(GridView.AUTO_FIT);
grid.setVerticalSpacing(5);
grid.setHorizontalSpacing(5);
grid.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
}
adapter = new GAdapter(mActivity, myInformation);
grid.setAdapter(adapter);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
refresh();
return grid;
}
public class GAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<xThumbnail> mInfo;
// Gets the context so it can be used later
public GAdapter(Context c, ArrayList<xThumbnail> info) {
mInfo = info;
mContext = c;
}
// Total number of things contained within the adapter
public int getCount() {
return mInfo.size();
}
public xThumbnail getItem(int position) {
return mInfo.get(position);
}
// Require for structure, not really used in my code. Can
// be used to get the id of an item in the adapter for
// manual control.
public long getItemId(int position) {
return position;
}
public View getView(final int position,
View convertView, ViewGroup parent) {
View v;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.thumbnail, null);
final TextView tv = (TextView) v.findViewById(R.id.tvClickMe);
final ProgressBar pb = (ProgressBar) v.findViewById(R.id.prgb_progress);
pb.setProgress(mInfo.get(position).getProgress());
tv.setText(mInfo.get(position).getProgress() + "");
mInfo.get(position).setProgressBar(pb);
mInfo.get(position).setTextView(tv);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runOp(mInfo.get(position), position, this_fragment_name);
}
});
} else {
v = convertView;
}
return v;
}
}
private void runOp(final xThumbnail x, final int position, final fragment_names f_name) {
if (x.xt == null) {
x.xt = new Thread(new Runnable() {
#Override
public void run() {
for (int i = x.getProgress(); i <= 100; i++) {
// UNCOMMENT IF YOU WANT TO STOP THE PROCESS AFTER SWITCHING
// if ((f_name == this_fragment_name) && !mThread.isInterrupted()) {
final int progress = i;
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
x.setProgressBar(adapter.getItem(position).getProgressBar());
x.setTextView(adapter.getItem(position).getTextView());
x.setProgress(progress);
x.getProgressBar().setProgress(progress);
x.getTextView().setText(progress + "");
// ARBITRARY CHANGE OF MYINFORMATION
// JUST TO SHOW THAT IT WORKS
if (progress == 20) {
myInformation.get(3).setProgress(12);
refresh();
}
// **********************************
}
});
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
// } else {
// return;
// }
}
}
});
}
if (!x.xt.isAlive())
x.xt.start();
}
}
The fr1.java:
public class fr1 extends GridFragment {
static ArrayList<xThumbnail> fr1Info;
public static fr1 newInstance(Activity act) {
mActivity = act;
return new fr1();
}
#Override
protected void refresh() {
if (fr1Info == null || fr1Info.size() == 0) {
fr1Info = new ArrayList<>();
for (int i = 0; i < 10; i++) {
xThumbnail x;
x = new xThumbnail();
fr1Info.add(x);
}
}
myInformation = fr1Info;
super.refresh();
}
}
The fr2.java:
public class fr2 extends GridFragment {
static ArrayList<xThumbnail> fr2Info;
public static fr2 newInstance(Activity act) {
mActivity = act;
return new fr2();
}
#Override
protected void refresh() {
if (fr2Info == null || fr2Info.size() == 0) {
fr2Info = new ArrayList<>();
for (int i = 0; i < 10; i++) {
xThumbnail x;
x = new xThumbnail();
fr2Info.add(x);
}
}
myInformation = fr2Info;
super.refresh();
}
}
The xThumbnail.java (model):
public class xThumbnail {
private int prgb_value = 0;
private ProgressBar pb;
private TextView tv;
public Thread xt;
public void setProgress(Integer i) {
prgb_value = i;
}
public Integer getProgress() {
return prgb_value;
}
public void setProgressBar(ProgressBar prb) {
pb = prb;
}
public ProgressBar getProgressBar() {
return pb;
}
public void setTextView(TextView tv) {
this.tv = tv;
}
public TextView getTextView() {
return tv;
}
}
The MainActivity.java:
public class MainActivity extends AppCompatActivity {
Button btn_one, btn_two;
fr1 mFr1;
fr2 mFr2;
FragmentManager fm = getFragmentManager();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_one = (Button) findViewById(R.id.btn_one);
btn_two = (Button) findViewById(R.id.btn_two);
mFr1 = (fr1) fm.findFragmentByTag("fr1");
mFr2 = (fr2) fm.findFragmentByTag("fr2");
final FrameLayout frameLayout = (FrameLayout)findViewById(R.id.frLayout);
btn_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GridFragment.this_fragment_name= GridFragment.fragment_names.FR1;
if (mFr1 == null) {
mFr1 = fr1.newInstance(MainActivity.this);
fm.beginTransaction().add(R.id.frLayout, mFr1, "fr1").commit();
} else {
fm.beginTransaction().detach(mFr1).commit();
fm.beginTransaction().attach(mFr1).commit();
}
}
});
btn_two.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
GridFragment.this_fragment_name= GridFragment.fragment_names.FR2;
if (mFr2 == null) {
mFr2 = fr2.newInstance(MainActivity.this);
fm.beginTransaction().add(R.id.frLayout, mFr2, "fr2").commit();
} else{
fm.beginTransaction().detach(mFr2).commit();
fm.beginTransaction().attach(mFr2).commit();
}
}
});
}
}
activity_main.xml:
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:id="#+id/btn_one"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
android:id="#+id/btn_two"
android:layout_alignParentBottom="true"
android:layout_alignRight="#+id/prgb_uni"
android:layout_alignEnd="#+id/prgb_uni" />
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/prgb_uni"
android:layout_alignParentBottom="true"
android:layout_marginBottom="40dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:id="#+id/frLayout"></FrameLayout>
</RelativeLayout>
thumbnail.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/prgb_progress" />
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="ClickMe!"
android:id="#+id/tvClickMe"
android:layout_gravity="center_horizontal"
android:textIsSelectable="false" />
</FrameLayout>
What it does:
We have here one base class, it operates with representation of views and populating progress bars.
It has field to work with current items (that holds progress bar values), every time when we switching between fragments this field is updated to respective values of Fragment1 or Fragment2, those fragments have static fields to hold their own data so it can be changed and used.
The thing with Thread and some other code is just to show that it's works and for better understanding.
I hope it will help.
PoC - https://youtu.be/uKGeX40z_mA :)

As an abstract blueprint you could add a download Service to your app and let it to download your materials.
For communicating with this service you might want to declare it as a bind-able service so that whenever user switch to that fragment your activity can bind to this service and see what is going on.
Using this way, you can report download progress to user and also you no longer need sending broadcasts.

Related

Button not causing the onClick event

I'm working on an app (part of a project in school), and I have an activity, that consists of an ImageView, a SearchView, a ListView, and a Button.
I'm trying to put the button in front of the ListView, which was working gucci until I got to the actual making the button do something part.
After setting the onClick method, I noticed that the button didn't do anything. I tried just printing something using the button, but nothing worked. Also tried creating a new button, outside the ListView, but that also failed (also didn't cause the onClick event).
I am kinda clueless, and cannot think of anything that could've caused this problem...
xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="#color/main_color"
android:orientation="vertical"
android:divider="#android:color/transparent"
android:dividerHeight="10.0sp"
android:layout_gravity="center"
tools:context=".SetupActivity">
<ImageView
android:layout_width="300dp"
android:layout_gravity="center"
android:layout_height="130dp"
android:layout_marginTop="13dp"
android:background="#drawable/setup_text"
android:id="#+id/setupText"
></ImageView>
<androidx.appcompat.widget.SearchView
android:layout_width="match_parent"
android:layout_height="65dp"
android:id="#+id/searchViewSetup"
android:theme="#style/AppTheme.Toolbar"
app:iconifiedByDefault="false"
></androidx.appcompat.widget.SearchView>
<RelativeLayout
android:layout_width="wrap_content"
android:paddingHorizontal="8dp"
android:layout_height="wrap_content">
<ListView
android:id="#+id/list_item"
android:layout_gravity="center"
android:layout_width="395dp"
android:divider="#android:color/transparent"
android:dividerHeight="10.0sp"
android:layout_height="wrap_content"
tools:listitem="#layout/activity_ingredients_layout"
android:paddingBottom="10.0sp"
android:clipToPadding="false"
android:scrollbars="none"
android:paddingTop="10.0sp">
</ListView>
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#drawable/setup_btn_shadow"
android:layout_marginLeft="287dp"
android:layout_marginTop="450dp"
android:alpha="0.5"
></ImageView>
<android.widget.Button
android:layout_width="73dp"
android:id="#+id/setup_floating_btn"
android:layout_height="73dp"
android:layout_marginLeft="300dp"
android:layout_marginTop="460dp"
android:foregroundGravity="bottom"
android:src="#drawable/ic_baseline_arrow_forward_ios_24"
android:background="#drawable/setup_btn"
></android.widget.Button>
</RelativeLayout>
</LinearLayout>
java:
package com.example.yummilyproject;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import com.example.yummilyproject.databinding.ActivitySetupFridgeBinding;
import java.util.ArrayList;
public class SetupActivity extends AppCompatActivity implements View.OnClickListener {
ActivitySetupFridgeBinding binding;
SearchView searchView;
ListView listView;
Button btn;
String[] ingredients = {"Avocado", "Tomato", "Pasta", "Cauliflower", "Egg", "Salmon", "Chicken", "Beef", "Broccoli", "Cheese", "Zucchini", "Lemon", "Sweet Potato", "Kale", "Carrot", "Black Beans", "Asparagus",
"Spinach", "Rice", "Potato", "Yoyo Beans"};
Boolean[] checkboxes = {false, false, false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false};
int[] images = {R.drawable.ic_launcher_foreground, R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground,R.drawable.ic_launcher_foreground};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_setup_fridge);
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
listView = findViewById(R.id.list_item);
searchView = findViewById(R.id.searchViewSetup);
btn = (Button) findViewById(R.id.setup_floating_btn);
btn.bringToFront();
btn.setOnClickListener(this);
binding = ActivitySetupFridgeBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ArrayList<Ingredient> ingredientArrayList = new ArrayList<>();
for (int i = 0; i < images.length; i++) {
Ingredient ingredient = new Ingredient(ingredients[i], images[i], checkboxes[i]);
ingredientArrayList.add(ingredient);
}
ListAdapter listAdapter = new ListAdapter(SetupActivity.this, ingredientArrayList);
binding.listItem.setTextFilterEnabled(true);
binding.listItem.setAdapter(listAdapter);
binding.listItem.setClickable(true);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
listAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
listAdapter.getFilter().filter(newText);
return false;
}
});
binding.listItem.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Ingredient ig = (Ingredient) parent.getItemAtPosition(position);
ig.setIngredientCheckBox(!ig.isIngredientCheckBox());
CheckBox cb = view.findViewById(R.id.ingredientChekcBox);
cb.setChecked(!cb.isChecked());
//cb.setChecked(!cb.isChecked());
}
});
}
#Override
public void onClick(View v) {
v.startAnimation(buttonClick);
if (v == findViewById(R.id.setup_floating_btn))
{
System.out.println("press btn");
String[] ingredientsList = new String[ingredients.length];
int cnt = 0;
for (int i = 0; i<ingredients.length; i++)
{
if (checkboxes[i] == true)
{
ingredientsList[cnt] = ingredients[i];
cnt++;
}
}
System.out.println(ingredientsList);
Intent intent = new Intent (this, MainActivity.class);
intent.putExtra("ingredientsList", ingredientsList);
}
}
private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);
public class Ingredient
{
private String ingredientTitle;
private int ingredientPhoto;
private boolean ingredientCheckBox;
public Ingredient(String ingredientTitle, int ingredientPhoto, boolean ingredientCheckBox) {
this.ingredientTitle = ingredientTitle;
this.ingredientPhoto = ingredientPhoto;
this.ingredientCheckBox = ingredientCheckBox;
}
public String getIngredientTitle() {
return ingredientTitle;
}
public void setIngredientTitle(String ingredientTitle) {
this.ingredientTitle = ingredientTitle;
}
public int getIngredientPhoto() {
return ingredientPhoto;
}
public void setIngredientPhoto(int ingredientPhoto) {
this.ingredientPhoto = ingredientPhoto;
}
public boolean isIngredientCheckBox() {
return ingredientCheckBox;
}
public void setIngredientCheckBox(boolean ingredientCheckBox) {
this.ingredientCheckBox = ingredientCheckBox;
}
}
public class ListAdapter extends ArrayAdapter<Ingredient>
{
public ListAdapter (Context context, ArrayList<Ingredient> ingredientList)
{
super(context, R.layout.activity_ingredients_layout, ingredientList);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
Ingredient ingredient = getItem(position);
if (convertView == null)
{
convertView = LayoutInflater.from(getContext()).inflate(R.layout.activity_ingredients_layout, parent, false);
}
ImageView imageView = convertView.findViewById(R.id.ingredientPhoto);
TextView title = convertView.findViewById(R.id.ingredientTitle);
CheckBox cb = convertView.findViewById(R.id.ingredientChekcBox);
imageView.setImageResource(ingredient.ingredientPhoto);
title.setText(ingredient.ingredientTitle);
cb.setActivated(ingredient.ingredientCheckBox);
return convertView;
}
}
public void finish() {
super.finish();
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
}
}
Your way of using equality is wrong. You cannot use == to see if two objects are equal to each other.
If you really want to use equals to verify it's the same object, you should do this instead:
if (v.equals(findViewById(R.id.setup_floating_btn)) {
// Do whatever you need to do when the button is clicked here.
}
While this can work, it's not the recommended way of verifying whether this was the View clicked. Instead you should check the clicked View's ID like this:
if (v.getId() == R.id.setup_floating_btn) {
// Do whatever you need to do when the button is clicked.
}
Have a look at the difference between equals and == here.
On a side-note: you're mixing things together here - ViewBindings with normal findViewById which is really bad and makes things very difficult to read. ViewBindings are meant to make it easier to inflate all views in a screen as well as making all references to views type-safe and making sure no views are null. You should probably read up on this too.
Also in your XML you use sp as units for dividerHeight and padding, which is completely wrong. sp units are used only for text and not for heights or paddings of views.
Also take a look at what bringToFront() does on a View and see if this really should apply/be used on your Button.

How to assign buttons on different spots of 70 images separately?

My Problem:
I have 70 images, and on each image I want to put transparent button
in such a way that when user taps on it, it plays a short audio
regarding the spot on image. Images are displaying in a ViewPager.
My Solution:
Now what I have in mind is I can create 70 fragments each containing respective image as background and I can assign button on each spot easily and assign actions to those buttons which will play their respective audio.
But
this doesn’t look like a good approach to include 70 fragments in a single app.
So how can I achieve this, and what would be a better approach I can use?
We can just have one fragment and create an ArrayList of Map(Button, RelatedAudioFile) data structure for holding buttons and related audio files. ArrayList index represents the page number.
Example:
Now lets say we have 3 viewPages. As most of the PagerAdapter index start from "0", let say Page-0 contains 3 buttons, Page-1 contains 1 button, Page-2 contains 2 buttons.
Pseudocode:
class PagerHolder extends Fragment {
//buttons list - here, arrayList index represents page number
//and at each index we have map of buttons (buttons in each of these pages) and the related audio files
private ArrayList<Map<Button, RelatedAudioFile>> pageButtonsList = new ArrayList<>();
//pager view
private ViewPager viewPager;
//pager adapter
private PagerAdapter pagerAdapter;
//current page number -- page in which we are in right now
private int currentpageNumber = 0;
//buttonListener -- one button listener for all the buttons in all the pages.
private View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View buttonView) {
//here you can play the audio.
//buttonView -- is the same button-object that was pressed.
((RelatedAudioFile)pageButtonsList.get(currentpageNumber).get(buttonView)).play();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pagerAdapter = new PagerAdapter(getChildFragmentManager());
//add buttons to the list
//page 0 buttons
HashMap<Button, RelatedAudioFile> page0Buttons = new HashMap<>();
page0Buttons.put(new Button(context), new RelatedAudioFile());
page0Buttons.put(new Button(context), new RelatedAudioFile());
page0Buttons.put(new Button(context), new RelatedAudioFile());
pageButtonsList.add(page0Buttons)
//Adding page 1 buttons:
HashMap<Button, RelatedAudioFile> page1Buttons = new HashMap<>();
page1Buttons.put(new Button(context), new RelatedAudioFile());
pageButtonsList.add(page1Buttons);
//Adding page 2 buttons:
HashMap<Button, RelatedAudioFile> page2Buttons = new HashMap<>();
page2Buttons.put(new Button(context), new RelatedAudioFile());
page2Buttons.put(new Button(context), new RelatedAudioFile());
pageButtonsList.add(page2Buttons);
for(Map<Button, RelatedAudioFile> pageButtons :pageButtonsList) {
for(Button button : pageButtons.keySet()) {
button.setOnClickListener(listener);
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_editor_pager, container, false);
viewPager = (ViewPager) v.findViewById(R.id.view_pager);
viewPager.setAdapter(pagerAdapter);
return v;
}
private class PagerAdapter extends FragmentPagerAdapter {
private ButtonFragment buttonFragment;
private PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pageNumber) {
currentpageNumber = pageNumber;
//pass the buttons to the fragment so that it can add these buttons to the screen
buttonFragment = ButtonFragment.newInstance(pageButtonsList.get(pageNumber).keySet());
//to add buttons on screen programatically at certain position you can refer here:
// http://stackoverflow.com/questions/3441475/android-change-absolute-position-of-a-view-programmatically
}
//number of pages
#Override
public int getCount() {
return 70;
}
}
You dont have to create 70 fragments. Instead, you could just use one ImageView as follows:
final List<Integer> list = new ArrayList<>();
list.add(R.drawable.img_0);
list.add(R.drawable.img_1);
...
list.add(R.drawable.img_69);
ImageView img = (ImageView)findViewById(R.id.imageView);
img.setBackgroundResource(list.get(yourIndex));
img.setOnClickListener(new OnClickListener());//plays the audio
You don't need to declare 70 fragments, just create one fragment and on that fragment declare global arrays of images and sound. Now when you redirect here at fragment just pass one integer variable in argument. So now you can display the image from array using that integer variable and on button click you can play audio from sound array using same integer number.
Use this custom view pager
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* Created by Jinesh on 06-01-2016.
*/
public class CustomViewPager extends ViewPager {
private boolean enabled;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.enabled = true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onTouchEvent(event);
}
return false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
/*
if (this.enabled) {
return super.onInterceptTouchEvent(event);
}
*/
return false;
}
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
}
Add this tag to your xml
<Your_package_name.CustomViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/vP_asq_Pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
Then extend PagerAdapter
public class HomeAdapter extends PagerAdapter {
public HomeAdapter(){
}
#Override
public int getCount() {
return mItemList.size();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext().getSystemService(LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.adapter_surveyquestion_view, null);
/*do your operations on your views here
store the 70 images in arraylist and return the size of the arraylist in getCount() method of the adapter.show different images each time in
getView based on the position variable.*/
(container).addView(v);
return v;
}
#Override
public boolean isViewFromObject (View view, Object object){
return view == ((View) object);
}
#Override
public void restoreState (Parcelable arg0, ClassLoader arg1){
}
#Override
public Parcelable saveState () {
return null;
}
#Override
public void destroyItem (ViewGroup container,int position, Object object){
container.removeView((View) object);
}
}
This is how I would do. Pleas note that this is a single class solution for example purpose, you can separate classes
This will keep only 5 fragments at a time
Screen is divided into 4 buttons you can set alpha value of buttons and size as per need currently i kept it half transparent for example
I am using Glide for image loading to avoid OOM problem because of image loading
What it look like
The Solution :-
package com.example.sample;
import java.util.ArrayList;
import com.bumptech.glide.Glide;
import android.content.Context;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class MainActivity extends FragmentActivity {
private static ArrayList<Integer> imageList = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Load image data
for (int i = 0; i < 70; i++) {
imageList.add(R.drawable.ic_launcher);
}
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
ViewPager viewPager = (ViewPager) rootView
.findViewById(R.id.image_pager);
// Limit number of pages that should be retained to either
// side of the current page
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(new SongDetailAdapter(getActivity()));
return rootView;
}
}
public static class SongDetailAdapter extends PagerAdapter {
Context mContext;
LayoutInflater mLayoutInflater;
public SongDetailAdapter(Context context) {
mContext = context;
mLayoutInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return imageList.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((FrameLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View itemView = mLayoutInflater.inflate(
R.layout.image_place_holder, container, false);
ImageView imageView = (ImageView) itemView
.findViewById(R.id.background);
itemView.findViewById(R.id.button1).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
playSound(1);
}
});
itemView.findViewById(R.id.button2).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
playSound(2);
}
});
itemView.findViewById(R.id.button3).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
playSound(3);
}
});
itemView.findViewById(R.id.button4).setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
playSound(4);
}
});
Glide.with(mContext).load("").placeholder(imageList.get(position))
.crossFade(300).into(imageView);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((FrameLayout) object);
}
#Override
public Object instantiateItem(View arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
#Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
/*
* Play sound
*/
private void playSound(int buttonNumber) {
switch (buttonNumber) {
case 1: // play sound for Button1
case 2: // play sound for Button2
case 3: // play sound for Button3
case 4: // play sound for Button4
default: // play sound for Button n
// Playing default notification here for example
Uri notification = RingtoneManager
.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager
.getRingtone(mContext, notification);
r.play();
break;
}
}
}
}
Layouts
Main Activity layout activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.sample.MainActivity"
tools:ignore="MergeRootFrame" />
Main fragment layout fragment_main.xml
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.sample.MainActivity$PlaceholderFragment" >
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/image_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Image place holder with dummy buttons imae_place_holder.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:orientation="horizontal" >
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:alpha=".5"
android:background="#android:color/white"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:alpha=".5"
android:background="#android:color/holo_green_light"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:orientation="horizontal" >
<Button
android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:alpha=".5"
android:background="#android:color/holo_blue_light"
android:text="Button" />
<Button
android:id="#+id/button4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:alpha=".5"
android:background="#android:color/holo_red_light"
android:text="Button" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

spinner initialization in a custom view

I try to make a custom view but I've got a problem with the spinner.
When I launch the application everything is ok. Preferences are read and the spinner setSelection method work great (display picture is ok).
When I change the spinner value, there is no problem too : Preferences are saved and when I start the application the new choice is display.
My problem comes when rotating the device, all my spinner value are reset to the last spinner value (vv2 in my code). I really don't understand...
Here is my code :
The widget_value_view.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<Spinner
android:id="#+id/my_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="#android:color/transparent" />
<TextView
android:id="#+id/my_value_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_centerVertical="true"
android:background="#android:color/transparent" />
</merge>
The ValueView.java class :
package com.example.spinnertest;
import java.util.Arrays;
import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
public class ValueView extends LinearLayout {
protected TextView mValueTv = null;
protected Spinner mSpinner = null;
protected List<String> mChoiceList;
private MySpinnerAdapter mSpinnerAdapter;
public ValueView(Context context) {
super(context);
}
public ValueView(Context context, AttributeSet attributes){
super(context,attributes);
TypedArray a = context.getTheme().obtainStyledAttributes(attributes,R.styleable.ValueView,0, 0);
try {
String valueList = a.getString(R.styleable.ValueView_valueList);
mChoiceList = Arrays.asList(valueList.split("\\|"));
} finally {
a.recycle();
}
setOrientation(LinearLayout.HORIZONTAL);
setGravity(Gravity.CENTER_VERTICAL);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.widget_value_view, this, true);
mSpinner = (Spinner) getChildAt(0);
mValueTv = (TextView) getChildAt(1);
mSpinnerAdapter = new MySpinnerAdapter(context, mChoiceList);
mSpinner.setAdapter(mSpinnerAdapter);
}
/**
* Change textview value
*/
public void setValue(double value,String format){
mValueTv.setText("todo");
invalidate();
requestLayout();
}
/**
* Set the current item of the spinner
* #param position of the item
*/
public void setSelection(int position, boolean animate) {
// mSpinnerAdapter.notifyDataSetChanged();
mSpinner.setSelection(position,animate);
// invalidate();
// requestLayout();
}
public int getSelectedItemPosition() {
return mSpinner.getSelectedItemPosition();
}
}
In this class I use a adapter define with 2 layout and one class :
MySpinnerAdapter.java
package com.example.spinnertest;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MySpinnerAdapter extends BaseAdapter {
public static final String ITEM_ALTITUDE = "altitude";
public static final String ITEM_SPEED = "speed";
public static final String ITEM_DISTANCE = "distance";
private static final String LOG_TAG = "SPINNER_TEST";
private Context mContext;
private List<String> mChoiceList;
public MySpinnerAdapter(Context context, List<String> values) {
this.mContext = context;
this.mChoiceList = values;
}
#Override
public int getCount() {
return mChoiceList.size();
}
#Override
public Object getItem(int position) {
return mChoiceList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater layout = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layout.inflate(R.layout.item_spinner_value, null);
}
ImageView imView = (ImageView) convertView.findViewById(R.id.item_spinner_value_iv);
Log.d(LOG_TAG,"Spinner Adapter position = " + String.valueOf(position));
imView.setImageResource(getSpinnerItemImage(position));
return convertView;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater layout = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layout.inflate(R.layout.item_spinner_list, null);
}
ImageView imView = (ImageView) convertView.findViewById(R.id.item_spinner_list_iv);
TextView textView = (TextView) convertView.findViewById(R.id.item_spinner_list_tv);
textView.setText(mChoiceList.get(position));
imView.setImageResource(getSpinnerItemImageSmall(position));
return convertView;
}
private int getSpinnerItemImageSmall(int position) {
String item = mChoiceList.get(position);
if (item.equals(ITEM_ALTITUDE)) {
return R.drawable.altitude_small;
} else if (item.equals(ITEM_DISTANCE)) {
return R.drawable.distance_small;
} else if (item.equals(ITEM_SPEED)) {
return R.drawable.vitesse_small;
} else {
return R.drawable.date_small;
}
}
private int getSpinnerItemImage(int position) {
String item = mChoiceList.get(position);
if (item.equals(ITEM_ALTITUDE)) {
return R.drawable.altitude;
} else if (item.equals(ITEM_DISTANCE)) {
return R.drawable.distance;
} else if (item.equals(ITEM_SPEED)) {
return R.drawable.vitesse;
} else {
return R.drawable.date;
}
}
}
and the 2 layout item_spinner_list.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/item_spinner_list_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="5dp"
android:src="#android:drawable/ic_menu_gallery" />
<TextView
android:id="#+id/item_spinner_list_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="5dp"
android:layout_toRightOf="#+id/item_spinner_list_iv"
android:text="Durée" />
</RelativeLayout>
and item_spinner_value.xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent" >
<ImageView
android:id="#+id/item_spinner_value_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="5dp"
android:src="#android:drawable/ic_menu_gallery" />
</RelativeLayout>
and finally my MainActivity.java
package com.example.spinnertest;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
public class MainActivity extends Activity {
private SharedPreferences mPref;
private ValueView mVv1;
private ValueView mVv2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mVv1 = (ValueView)findViewById(R.id.value1);
mVv2 = (ValueView)findViewById(R.id.value2);
mVv1.setSelection(mPref.getInt("pref_val1", 0),false);
mVv2.setSelection(mPref.getInt("pref_val2", 1),false);
}
#Override
public void onPause() {
SharedPreferences.Editor editor = mPref.edit();
editor.putInt("pref_val1", mVv1.getSelectedItemPosition());
editor.putInt("pref_val2", mVv2.getSelectedItemPosition());
editor.commit();
super.onPause();
}
}
and the layout :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.example.spinnertest"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.spinnertest.ValueView
android:id="#+id/value1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_margin="10dp"
android:background="#android:color/transparent"
custom:valueList="speed|altitude|distance" />
<com.example.spinnertest.ValueView
android:id="#+id/value2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/value1"
android:layout_margin="10dp"
custom:valueList="speed|altitude|distance" />
</RelativeLayout>
I cannot really explain why your code is not working, but I would prefer to save the state of the spinner locally (I mean in the activity); it's the normal Android workflow for screen rotation.
Something like this:
String MVV1="1";
String MVV2="2";
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mVv1 = (ValueView)findViewById(R.id.value1);
mVv2 = (ValueView)findViewById(R.id.value2);
if (savedInstanceState != null) {
mVv1.setSelection(savedInstanceState.getInt(MVV1),false);
mVv2.setSelection(savedInstanceState.getInt(MVV2),false);
}
else{
mVv1.setSelection(mPref.getInt("pref_val1", 0),false);
mVv2.setSelection(mPref.getInt("pref_val2", 1),false);
}
}
#Override
public void onPause() {
SharedPreferences.Editor editor = mPref.edit();
editor.putInt("pref_val1", mVv1.getSelectedItemPosition());
editor.putInt("pref_val2", mVv2.getSelectedItemPosition());
editor.commit();
super.onPause();
}
#Override
protected void onSaveInstanceState (Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(MVV1, mVv1.getSelectedItemPosition());
outState.putInt(MVV2, mVv2.getSelectedItemPosition());
}
My syntax is maybe not perfect because I wrote it in the SO editor but hope you got the idea: the status is written in the Preferences as soon as the Activity is paused but if the activity rotates (your method should work but maybe is there a cache to access to the preferences or something...) then, it'll use the specific bundle for it: the one which is filled just when the screen rotates and used when the screen is recreated.
Test it and say if it's working ;)

ListView no longer display inside Tab

I haven't touched this codebase in a couple of months. Now that I've picked it up again, some code that I didn't think I'd changed has stopped working: All listfragment listviews in the app populated by a simplecursoradapter have stopped working and are just blank. At first I thought the cursor or the database was at fault or that perhaps the adapter wasn't being set correctly, so I added some debugging to the onLoadFinished:
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
Log.d("IndexListFragment", "Rows returned: " + cursor.getCount());
Log.d("IndexListFragment", cursor.getColumnName(0));
Log.d("IndexListFragment", mAdapter.toString());
Log.d("IndexListFragment", this.getListView().getAdapter().toString());
mAdapter.swapCursor(cursor);
}
This returns what I'd expect:
IndexListFragment: Rows returned: 2324
IndexListFragment: _id
IndexListFragment: android.support.v4.widget.SimpleCursorAdapter#41d06a18
IndexListFragment: android.support.v4.widget.SimpleCursorAdapter#41d06a18
So as far as I can tell, the cursor is there and full of data, but swapping it in doesn't get the listview populated. Any ideas?
For completeness, here's the onCreate where the adapter is created and set:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] from = new String[] { GuidebookProvider.COL_NAME,
GuidebookProvider.COL_GRADE };
int[] to = new int[] { android.R.id.text1, android.R.id.text2 };
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_2, null, from, to, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
And the onCreateLoader:
#Override
public Loader<Cursor> onCreateLoader(int loaderId, Bundle loaderArgs) {
String orderBy = GuidebookProvider.COL_NAME;
String[] projection = new String[] { GuidebookProvider.COL_ID, GuidebookProvider.COL_NAME, GuidebookProvider.COL_GRADE };
return new CursorLoader(getActivity(),
GuidebookProvider.CONTENT_URI_CLIMB, projection, null, null,
orderBy);
}
Edit: I've done a little more work debugging this issue. The fragment works fine if I run it directly from an activity like this:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.widget.FrameLayout;
public class TestActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout frame = new FrameLayout(this);
frame.setId(android.R.id.content);
if (savedInstanceState == null) {
Bundle args = new Bundle();
args.putInt(IndexListFragment.ARGUMENT_INDEX_TYPE, IndexListFragment.IndexType.ALPHA.value);
Fragment indexListFragment = new IndexListFragment();
indexListFragment.setArguments(args);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(android.R.id.content, indexListFragment).commit();
}
}
}
However, calling it as part of a Tab ends up with a blank tab:
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
public class TestActivity extends FragmentActivity {
private FragmentTabHost mTabHost;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_tab_host);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
Bundle args = new Bundle();
args.putInt(IndexListFragment.ARGUMENT_INDEX_TYPE,
IndexListFragment.IndexType.ALPHA.value);
Drawable drawable = null;
mTabHost.addTab(mTabHost.newTabSpec("A-Z")
.setIndicator("A-Z", drawable), IndexListFragment.class, args);
}
}
Here's my xml for the tabhost:
<?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="match_parent"
android:orientation="vertical" >
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
The fact that the fragment populates correctly when called directly but not when called from within a tab seems to show that the problem isn't at all with the cursors or adapters but with the way the listfragment operating inside a tab.
Can anyone point out what I've done wrong (or what's changed in the last couple of updates of the SDK) to break this code? It used to work fine.
This Code may help you just try it
ViewAllLesson.java :
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import com.xyz.R;
import com.xyz.db.LessonDatabaseConnector;
import com.xyz.pojo.AssignmentPojo;
import com.xyz.pojo.LessonPojo;
public class ViewAllLessons extends Fragment {
public LessonDatabaseConnector dao;
private View rootView;
List<LessonPojo> lessons;
ArrayList<String> con = new ArrayList<String>();
LayoutInflater mInflater;
LessonCustomAdapter lessonCustomAdapter;
private ListView listView;
public static CheckBox selectAll;
private Button deleteBtn;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.add_exams);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.lesson_view_all_list, container,
false);
// dao = new AssignmentDatabaseConnector(getActivity());
listView = (ListView) rootView.findViewById(R.id.Lesson_ListAll);
selectAll = (CheckBox) rootView.findViewById(R.id.SelectAll);
deleteBtn = (Button) rootView.findViewById(R.id.LessonDeleteBtn);
Button addNew = (Button) rootView.findViewById(R.id.LessonAddNewBtn);
addNew.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Toast.makeText(getActivity(), "hi",
// Toast.LENGTH_LONG).show();
Lesson lesson = new Lesson();
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, lesson).commit();
}
});
// viewgr.setScrollContainer(false);
dao = new LessonDatabaseConnector(getActivity());
lessons = dao.getAllLessonList();
lessonCustomAdapter = new LessonCustomAdapter(getActivity(), lessons,
this);
listView.setAdapter(lessonCustomAdapter);
/* To Check List View is empty */
if (lessons.size() <= 0) {
View empty = rootView.findViewById(R.id.empty);
ListView list = (ListView) rootView
.findViewById(R.id.Lesson_ListAll);
list.setEmptyView(empty);
listView.setVisibility(0);
empty.setVisibility(1);
}
selectAll.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Toast.makeText(getActivity(), "hi",
// Toast.LENGTH_LONG).show();
if (((CheckBox) v).isChecked()) {
LessonCustomAdapter.flag = true;
lessonCustomAdapter.notifyDataSetChanged();
} else {
LessonCustomAdapter.flag = false;
LessonCustomAdapter.checkedvalue.clear();
lessonCustomAdapter.notifyDataSetChanged();
}
}
});
// Set the list adapter and get TODOs list via DAO
deleteBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
LessonDatabaseConnector dao = new LessonDatabaseConnector(
getActivity());
for (int i = 0; i < LessonCustomAdapter.checkedvalue.size(); i++) {
//
System.out
.println("===========LessonCustomAdapter.checkedvalue.size()==========SIZE======>>>>"
+ LessonCustomAdapter.checkedvalue.size());
System.out
.println("===========DELETED LESSON=================>>>>"
+ LessonCustomAdapter.checkedvalue.get(i));
dao.DeleteLesson(LessonCustomAdapter.checkedvalue.get(i));
}
LessonCustomAdapter.flag = false;
ViewAllLessons viewAllLessons = new ViewAllLessons();
getFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, viewAllLessons)
.commit();
// finish();
}
});
return rootView;
}
private List<AssignmentPojo> getAllAssignmentsList() {
// TODO Auto-generated method stub
return null;
}
}
LessonCustomAdapter :
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import com.xyz.R;
import com.xyz.pojo.LessonPojo;
public class LessonCustomAdapter extends BaseAdapter {
protected static boolean flag = false;
private TextView mLessonTitle, mLessonDate;
private final Context context;
List<LessonPojo> Lessons;
private ViewAllLessons viewAllLessons;
private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();
private CheckBox SingleChk;
public static ArrayList<Long> checkedvalue = new ArrayList<Long>();
LessonCustomAdapter(Context context, List<LessonPojo> Lessons2,
ViewAllLessons viewAllLessons) {
this.context = context;
this.Lessons = Lessons2;
this.viewAllLessons = viewAllLessons;
for (int i = 0; i < Lessons2.size(); i++) {
itemChecked.add(i, false); // initializes all items value with false
}
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return Lessons.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View rowView = convertView;
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
rowView = inflater.inflate(R.layout.lesson_view_row_list, parent,
false);
}
mLessonDate = (TextView) rowView.findViewById(R.id.LessonDate);
mLessonDate.setText(Lessons.get(position).getLdate());
mLessonTitle = (TextView) rowView.findViewById(R.id.LessonTitle);
mLessonTitle.setText(Lessons.get(position).getLtitle());
SingleChk = (CheckBox) rowView.findViewById(R.id.singleChk);
/*
* if (flag) { System.out.println("66666666666666666666666666666666" +
* flag); for (int i = 0; i < Lessons.size(); i++) {
* SingleChk.setChecked(flag); SingleChk.setEnabled(!flag); }
*
* } else { SingleChk.setChecked(itemChecked.get(position)); }
*/
checkedvalue.clear();
if (ViewAllLessons.selectAll.isChecked()) {
SingleChk.setChecked(true);
Boolean val = false;
for (int i = 0; i < Lessons.size(); i++) {
checkedvalue.add(Long.parseLong(Lessons.get(i).getId()));
System.out
.println("ADD SUCCEFULLYYYYYYYY ====================== "
+ Long.parseLong(Lessons.get(position).getId()));
}
} else {
SingleChk.setChecked(false);
checkedvalue.clear();
}
rowView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Bundle bundle = new Bundle();
ViewSingleLesson viewSingleLesson = new ViewSingleLesson();
bundle.putString("ID", Lessons.get(position).getId());
bundle.putString("TITLE", Lessons.get(position).getLtitle());
bundle.putString("COURSE", Lessons.get(position).getLcourse());
bundle.putString("LEVEL", Lessons.get(position).getLlevel());
bundle.putString("CLASS", Lessons.get(position).getLclass());
bundle.putString("DATE", Lessons.get(position).getLdate());
bundle.putString("DESC", Lessons.get(position).getLdesc());
bundle.putString("ATTACH", Lessons.get(position).getLfilepath());
viewSingleLesson.setArguments(bundle);
viewAllLessons.getFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, viewSingleLesson)
.commit();
}
});
SingleChk.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Boolean val = false;
Toast.makeText(context, "hi " + Lessons.get(position).getId(),
Toast.LENGTH_LONG).show();
if (((CheckBox) v).isChecked()) {
for (int i = 0; i < checkedvalue.size(); i++) {
if (checkedvalue.get(i) == Long.parseLong(Lessons.get(
position).getId())) {
val = true;
System.out
.println("DUPLICATE ====================== "
+ Long.parseLong(Lessons.get(
position).getId()));
} else {
val = false;
}
}
if (val == false) {
checkedvalue.add(Long.parseLong(Lessons.get(position)
.getId()));
System.out
.println("ADD SUCCEFULLYYYYYYYY ====================== "
+ Long.parseLong(Lessons.get(position)
.getId()));
}
} else {
ViewAllLessons.selectAll.setChecked(false);
checkedvalue.remove(Long.parseLong(Lessons.get(position)
.getId()));
System.out
.println("Removed SUCCEFULLYYYYYYYY ====================== "
+ Integer.parseInt(Lessons.get(position)
.getId()));
// itemChecked.set(position, false);
}
}
});
return rowView;
}
}
Got a chance to have a look at this today and finally sorted it out. The problem was in my xml layout setup. Oddly, according to my git repository, this file hasn't changed for 9 months so I guess I was doing something that only worked by accident. I found a tutorial FragmentTabHosts with a different layout and updated my layout to:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</android.support.v4.app.FragmentTabHost>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
That somehow fixed the issue. A bit more hunting around revealed an example layout xml for FragmentTabHost in the TabActivity documentation: http://developer.android.com/reference/android/app/TabActivity.html
I updated to use the version found in the documentation and it also works:
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
Given I found it in Android's documentation, I'll stick with this version.

Android custom listview row

I'm struggling with assigning my listview row more than one textview.
I want my row to have one textview for a person's name, one for address and one for age - but I'm not succeeding in doing so.
If someone could provide me with a simple example, that would be great.
Thanks!
Here's my custom ArrayAdapter
import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater = null;
private ArrayList<Invoice> peopleList;
private final class ViewHolder {
TextView kidLabel;
TextView restLabel;
TextView fristLabel;
TextView amountLabel;
}
private ViewHolder mHolder = null;
public MyAdapter(Context context) {
Context mContext = context;
mInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return peopleList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
mHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.row, null);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
mHolder.kidLabel = (TextView) convertView.findViewById(R.id.kidLabel);
mHolder.kidLabel.setText(peopleList.get(position).getKID());
mHolder.fristLabel = (TextView) convertView
.findViewById(R.id.fristLabel);
mHolder.fristLabel.setText(peopleList.get(position).getDueDate());
mHolder.restLabel = (TextView) convertView.findViewById(R.id.restLabel);
mHolder.restLabel.setText(peopleList.get(position).getDueAmount());
mHolder.amountLabel = (TextView) convertView
.findViewById(R.id.amountLabel);
mHolder.amountLabel.setText(peopleList.get(position).getDueAmount());
return convertView;
}
}
And Here's my custom row xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:src="#drawable/cellback" android:scaleType="fitXY"/>
<TextView
android:id="#+id/kidLabel"
android:layout_width="160dip"
android:layout_height="25dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textSize="13dip" android:textColor="#333"/>
<TextView
android:id="#+id/fristLabel"
android:layout_width="160dip"
android:layout_height="20dip"
android:layout_marginTop="25dip"
android:textSize="11dip" android:textColor="#999"/>
<TextView
android:id="#+id/amountLabel"
android:layout_width="160dip"
android:layout_height="25dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textSize="13dip" android:layout_marginLeft="160dip" android:gravity="right" android:textColor="#333"/>
<TextView
android:id="#+id/restLabel"
android:layout_width="160dip"
android:layout_height="20dip"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textSize="11dip" android:layout_marginLeft="160dip" android:layout_marginTop="25dip" android:gravity="right" android:textColor="#999"/>
</RelativeLayout>
First,you should create a xml to describe what your list cell likes,called cell.xml,for example:
<?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="vertical" android:background="#color/spink">
<TextView
android:id="#+id/name_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/address_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
Second,create a adapter.It helps your listview to show data:
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater = null;
private ArrayList<People> peopleList;
private final class ViewHolder {
TextView nameTextView;
TextView addressTextView;
}
private ViewHolder mHolder = null;
public MyAdapter(Context context) {
mContext = context;
mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return peopleList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
mHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.cell, null);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder)convertView.getTag();
}
mHolder.nameTextView (TextView)convertView.findViewById(R.id.name_textView);
mHolder.nameTextView.setText(peopleList.get(position).getName());
mHolder.addressTextView = (TextView)convertView.findViewById(R.id.address_textView);
mHolder.addressTextView.setText(peopleList.get(position).getAddress());
return convertView;
}
}
Finally,when you want to show the data,do this in your activity:
listView.setAdapter(new MyAdapter());
hope it helps you.
You need to create a custom listview layout and a custom array adapter (I have also created a custom class to work with the layout).
An example of this is:
Custom class that works with the custom listview layout:
package id10778734.sceresini.week4.exercise3.views;
import id10778734.sceresini.week4.exercise3.R;
import id10778734.sceresini.week4.exercise3.Constants;
import id10778734.sceresini.week4.exercise3.tasks.Task;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class TaskListItem extends LinearLayout {
private Task mTask;
private ImageView mEmailImageView;
private ImageView mPriorityImageView;
private TextView mTaskNameTextView;
private TextView mTaskResponsibleTextView;
private ImageView mDeleteImageView;
public TaskListItem (Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public void onFinishInflate() {
super.onFinishInflate();
mEmailImageView = (ImageView) findViewById(R.id.list_row_layout_email_button);
mPriorityImageView = (ImageView) findViewById(R.id.list_row_layout_priority_icon);
mTaskNameTextView = (TextView) findViewById(R.id.list_row_layout_task_name);
mTaskResponsibleTextView = (TextView) findViewById(R.id.list_row_layout_responsible);
mDeleteImageView = (ImageView) findViewById(R.id.list_row_layout_delete_button);
}
public void setTask (Task task) {
mTask = task;
mEmailImageView.setTag(task);
switch (task.getPriority()) {
case Constants.LOW:
mPriorityImageView.setImageResource(R.drawable.low);
break;
case Constants.MEDIUM:
mPriorityImageView.setImageResource(R.drawable.medium);
break;
case Constants.HIGH:
mPriorityImageView.setImageResource(R.drawable.high);
break;
}
mTaskNameTextView.setText(task.getName());
mTaskResponsibleTextView.setText(task.getResponsible());
mDeleteImageView.setTag(task);
}
public Task getTask () {
return mTask;
}
public ImageView getDeleteImageView () {
return mDeleteImageView;
}
public ImageView getEmailImageView () {
return mEmailImageView;
}
}
the custom layout xml file:
<?xml version="1.0" encoding="UTF-8"?>
<id10778734.sceresini.week4.exercise3.views.TaskListItem
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dip" >
<ImageView
android:id="#+id/list_row_layout_email_button"
android:layout_width="36dip"
android:layout_height="36dip"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dip"
android:layout_marginRight="5dip"
android:contentDescription="#string/list_row_email_icon_description"
android:src="#android:drawable/ic_dialog_email" />
<ImageView
android:id="#+id/list_row_layout_priority_icon"
android:layout_width="24dip"
android:layout_height="24dip"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dip"
android:layout_marginRight="10dip"
android:contentDescription="#string/view_task_priority_icon_description" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" >
<TextView
android:id="#+id/list_row_layout_task_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/list_row_layout_responsible"
android:paddingRight="5dip"
android:textAppearance="#style/list_row_task_name" />
<TextView
android:id="#id/list_row_layout_responsible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/list_row_layout_delete_button"
android:maxWidth="100dip"
android:textAppearance="#style/list_row_task_responsible" />
<ImageView
android:id="#id/list_row_layout_delete_button"
android:layout_width="36dip"
android:layout_height="36dip"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="5dip"
android:layout_marginRight="5dip"
android:contentDescription="#string/delete_task_icon_description"
android:src="#drawable/task_delete" />
</RelativeLayout>
</id10778734.sceresini.week4.exercise3.views.TaskListItem>
And the custom array adapter:
package id10778734.sceresini.week4.exercise3;
import id10778734.sceresini.week4.exercise3.R;
import id10778734.sceresini.week4.exercise3.tasks.Task;
import id10778734.sceresini.week4.exercise3.views.TaskListItem;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class TaskListAdapter extends BaseAdapter
{
private ArrayList<Task> mTasks;
private Context mContext;
private AlertDialog unsavedChangesDialog;
private TaskManagerApplication mApp;
public TaskListAdapter(Context context, ArrayList<Task> tasks) {
super();
mApp = (TaskManagerApplication) context.getApplicationContext();
mContext = context;
mTasks = tasks;
}
#Override
public int getCount()
{
return mTasks.size();
}
#Override
public Task getItem(int position)
{
return (null == mTasks) ? null : mTasks.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
TaskListItem tli;
if (null == convertView)
{
tli = (TaskListItem) View.inflate(mContext, R.layout.list_row_layout, null);
} else
{
tli = (TaskListItem) convertView;
}
tli.setTask(mTasks.get(position));
tli.getEmailImageView().setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
emailTask(v);
}
});
tli.getDeleteImageView().setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
deleteTask(v);
}
});
return tli;
}
/**
* deleteTask() prompts the user with an alert dialog and presents them with
* the option to continue with the delete request or to cancel the request.
* Upon confirmation, the selected Task object which is retrieved from the
* deleteTaskIcon tag, will be removed from the list of currentTasks.
*
* #param v
*/
protected void deleteTask(View v)
{
final Task t = (Task) v.getTag();
String alertMessage = String.format(mContext.getString(R.string.delete_task_message), t.getName());
unsavedChangesDialog = new AlertDialog.Builder(mContext).setTitle(R.string.delete_task_title).setMessage(alertMessage)
// Delete the task and refresh the adapter.
.setPositiveButton(R.string.delete_task_delete, new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1)
{
// Remove task from array list
mTasks.remove(t);
// Remove task from Database
mApp.deleteTask(t);
// Display toast message stating the task was deleted
mApp.displayToast(Constants.TASK_DELETED);
// Update listView with modified adapter
forceReload();
}
})
// Cancel the delete request and do nothing.
.setNegativeButton(R.string.delete_task_cancel, new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1)
{
unsavedChangesDialog.cancel();
}
}).create();
unsavedChangesDialog.show();
}
/**
* emailTask() populates the selected task into an intent which allows the
* user to select a client to send the task. This is formatted for email
* clients.
*
* #param v
*/
protected void emailTask(View v)
{
// Retrieve the task that is allocated to this RowView
final Task t = (Task) v.getTag();
// Instantiate the intent that will be used to call the email client
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
// Variables/Arrays to hold email attributes
String[] emailRecipients = { mContext.getString(R.string.email_task_to_email) };
String emailType = mContext.getString(R.string.email_task_type);
String emailTitle = mContext.getString(R.string.email_task_title);
String emailSubject = String.format(mContext.getString(R.string.email_task_subject), t.getName());
String emailMessage = String.format(mContext.getString(R.string.email_task_message), t.getResponsible(), t.getName(), mContext.getString(t.getPriorityStringId()));
// Add the email attributes to the intent
emailIntent.setType(emailType);
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, emailRecipients);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, emailSubject);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, emailMessage);
// Start intent
mContext.startActivity(Intent.createChooser(emailIntent, emailTitle));
}
/**
* Refreshes the ListView with the modified dataset.
*/
public void forceReload()
{
notifyDataSetChanged();
}
}

Categories

Resources