I am trying to save a link from webview. From my webview class, I am saving the page url as below.
public void AddUrl(String page_url){
SaveUrlActivity urlactivity = new SaveUrlActivity();
urlactivity.saveurl(page_url);
}
My SaveUrlActivity class is as below:
public class SaveUrlActivity extends Activity {
public String url;
public ListView lv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_savedurl);
lv = (ListView) findViewById(R.id.list);
saveurl(url);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent in = new Intent(SaveUrlActivity.this, DisPlayWebPageActivity.class);
in.putExtra("page_url", url);
startActivity(in);
}
});
}
public void saveurl(String url1){
url = url1;
final List<RowItem> ri = new ArrayList<RowItem>();
RowItem item = new RowItem(url);
ri.add(item);
SavedUrlAdapter adapter = new SavedUrlAdapter(SaveUrlActivity.this, ri);
lv.setAdapter(adapter);
}
}
Whenever I run my program, I am getting the following error.
FATAL EXCEPTION: main
Process: com.example.smarthelp, PID: 16284
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.example.smarthelp.SaveUrlActivity.saveurl(SaveUrlActivity.java:46)
at com.example.smarthelp.DisPlayWebPageActivity.AddUrl(DisPlayWebPageActivity.java:76)
at com.example.smarthelp.DisPlayWebPageActivity.onOptionsItemSelected(DisPlayWebPageActivity.java:66)
Can anyone help me figure out where I am making the mistake?
You're using reference to ListView lv before it has been initialized, and you can't do that without first starting the SaveUrlActivity, only after it's setContentView(R.layout.activity_savedurl); you can initialize the lv.
public void saveurl(String url1){
url = url1;
final List<RowItem> ri = new ArrayList<RowItem>();
RowItem item = new RowItem(url);
ri.add(item);
SavedUrlAdapter adapter = new SavedUrlAdapter(SaveUrlActivity.this, ri);
lv.setAdapter(adapter);
}
It would be easier if you make a static var in your SaveUrlActivity class and assign a value to it before you start the Activity, and the make call to the saveurl() from inside of that class when you have all your views initialized.
Something like:
public void AddUrl(String page_url){
SaveUrlActivity.page_url = page_url;
Intent i = new Intent(this, SaveUrlActivity.class);
startActivity(i);
}
And in your SaveUrlActivity.java:
public class SaveUrlActivity extends Activity {
public String url;
public ListView lv;
static page_url;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_savedurl);
lv = (ListView) findViewById(R.id.list);
saveurl();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent in = new Intent(SaveUrlActivity.this, DisPlayWebPageActivity.class);
in.putExtra("page_url", url);
startActivity(in);
}
});
}
public void saveurl(){
url = page_url;
final List<RowItem> ri = new ArrayList<RowItem>();
RowItem item = new RowItem(url);
ri.add(item);
SavedUrlAdapter adapter = new SavedUrlAdapter(SaveUrlActivity.this, ri);
lv.setAdapter(adapter);
}
}
It's accurate if you're planning to start this activity, if you need to update data in already started one, you better use the Handler
A couple of things to look at:
Make sure that the activity_savedurl layout file actually contains a view with the list ID. If it does not, then lv will be null.
You pass url to saveurl(), but you never assigned it a value.
Related
How can I make this custom array list clickable to go to the others activities because I tried the intents but it doesn't work
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<Names> namesArrayList = new ArrayList<Names>();
namesArrayList.add(new Names(R.drawable.call_centre, "Call Centre"));
namesArrayList.add(new Names(R.drawable.soco_academy_icon, "Academy"));
NamesAdapter NamesListAdapter = new NamesAdapter(this, namesArrayList);
ListView list = (ListView) findViewById(R.id.List_View);
list.setAdapter(NamesListAdapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
}
In onItemClick() you can determine which item was clicked by doing this:
Name selectedName = NamesListAdapter.getItem(position);
Then you can do whatever you want with that.
I'm creating an android app. In this app, I have a ListView populated with data from SQLite. I am trying to add an onClickEventListener to each row of the ListView so that when a menu item is clicked it opens up another Activity with more information from the Database about the item clicked. I have succeeded in adding an event listener to the ListView, but I am not sure how to pass on database information depending on the list item clicked.
Here is my code:
public class MainActivity extends AppCompatActivity {
private DatabaseHelper dbh;
private ArrayList listItems = new ArrayList();
ArrayList<String[]> noteList;
private ArrayAdapter adapter;
private ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbh = new DatabaseHelper(this);
dbh.open();
lv = (ListView) findViewById(R.id.noteListView);
noteList = dbh.selectAll();
String id = "";
String content = "";
for(int i = 0; i < noteList.size(); i++){
content = noteList.get(i)[1];
id = noteList.get(i)[0];
listItems.add(id + ", " + content);
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, listItems);
lv.setAdapter(arrayAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Intent i = new Intent(MainActivity.this, EditNote.class);
//i.putExtra();
startActivity(i);
}
});
}
}
In your case list has strings, so here is what you need to do:
String yourString = listItem.get(position);
i.putExtra("KEY", yourString);
startActivity(i);
And at the receiving activity you can retrieve as
intent intent = getIntent();
String yourString = intent.getExtras().getString("KEY");
EDIT: If your list is having some POJO class or simple class objects
You can pass to second activity like this
intent.putExtra("Your class", obj);
To retrieve object in second Activity
getIntent().getSerializableExtra("Your class");
EDIT: One important thing to remember.
If you passing a class object it must implement Serializable or Parcelable interface.
For eg
class Student implements Serializable{
}
You should make a custom adapter that extends the arrayadapter. Load everything from your database into an arraylist and use something like this:
// CODE DOES NOT WORK WITH YOUR CODE, IT'S JUST AN EXAMPLE
public class MyClassAdapter extends ArrayAdapter<MyClass> {
private static class ViewHolder {
private TextView itemView;
}
public MyClassAdapter(Context context, int textViewResourceId, ArrayList<MyClass> items) {
super(context, textViewResourceId, items);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(this.getContext())
.inflate(R.layout.listview_association, parent, false);
viewHolder = new ViewHolder();
viewHolder.itemView = (TextView) convertView.findViewById(R.id.ItemView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
MyClass item = getItem(position);
if (item!= null) {
// My layout has only one TextView
// do whatever you want with your string and long
viewHolder.itemView.setText(String.format("%s %d", item.reason, item.long_val));
}
return convertView;
}
}
...
lv.setAdapter(new MyClassAdapter(....));
In your OnItemClickListener you have the position of the clicked item so to get the object use MyClass object = lv.getItemAtPosition(position); and use that object to pass data to the new activity.
Intent intent = new Intent(getBaseContext(), my.class);
intent.putExtra("key", "value");
startActivity(intent);
To access
String s = getIntent().getStringExtra("key");
More: https://stackoverflow.com/a/2265712/2890156
In here I am trying to make OnItemLongClick, I tried doing it in ListActivity before and that's working.
Now I am trying to make one inside a Fragment, but I get an error here and there, I need some advice/suggestion/answer to solve the error, or the correct way to implement the method.
In the ListActivity (working):
public class ViewData extends ListActivity implements OnItemLongClickListener {
//init controller
private DBDataSource dataSource;
//init arraylist
private ArrayList<Barang> values;
private Button delButton;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewdata);
dataSource = new DBDataSource(this);
// open controller
dataSource.open();
// get values
values = dataSource.getAllBarang();
// insert data to array adapter
ArrayAdapter<Barang> adapter = new ArrayAdapter<Barang>(this,
android.R.layout.simple_list_item_1, values);
// set adapter in list
setListAdapter(adapter);
// listview for set onItemLongClickListener
ListView lv = (ListView) findViewById(android.R.id.list);
lv.setOnItemLongClickListener(this);
}
//if user longclick
#Override
public boolean onItemLongClick(final AdapterView<?> adapter, View v, int pos,
final long id) {
//tampilkan alert dialog
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.dialog_view);
dialog.setTitle("Pilih Aksi");
dialog.show();
final Barang b = (Barang) getListAdapter().getItem(pos);
delButton = (Button) dialog.findViewById(R.id.button_delete_data);
//apabila tombol delete di klik
delButton.setOnClickListener(
new OnClickListener()
{
#Override
public void onClick(View v) {
// Delete barang
dataSource.deleteBarang(b.getId());
dialog.dismiss();
finish();
startActivity(getIntent());
}
}
);
return true;
}
}
The Fragment version (still giving an error) :
public class Menu_Riwayat extends Fragment {
//init controller
private DBDataSource dataSource;
//init arraylist
private ArrayList<Investasi_DB> values;
static ListView lv;
private Button button_hapus;
static LinearLayout mLinear;
#Nullable
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
mLinear = (LinearLayout) inflater.inflate(R.layout.viewdata, container, false);
lv = (ListView) mLinear.findViewById(R.id.list);
dataSource = new DBDataSource(getActivity());
// open controller
dataSource.open();
// get values
values = dataSource.getAllInvestasi_DB();
// insert data to array adapter
ArrayAdapter<Investasi_DB> adapter = new ArrayAdapter<Investasi_DB>(getActivity(),
android.R.layout.simple_list_item_1, values);
// set adapter in list
lv.setAdapter(adapter);
return mLinear;
// ERROR IN THIS PART BELOW, not sure what to change "this" with
lv.setOnItemClickListener(this);
}
public boolean onItemLongClick(final AdapterView<?> adapter, View v, int pos,
final long id) {
//tampilkan alert dialog
final Dialog dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.dialog_view);
dialog.setTitle("Pilihan");
dialog.show();
// ERROR IN THIS PART BELOW, not sure how to implement "getListAdapter()" inside fragment
final Investasi_DB b = (Investasi_DB) getListAdapter().getItem(pos);
button_hapus = (Button) dialog.findViewById(R.id.button_hapus);
button_hapus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dataSource.deleteInvestasi_DB(b.getId());
dialog.dismiss();
getActivity().finish();
// ERROR IN THIS PART BELOW, the "getIntent()" part
startActivity(getIntent());
}
});
return true;
}
}
I need help to solve the error (correct way to implement it):
getListAdapter(), getIntent(), and this in lv.setOnItemClickListener(this);
EDITED PART AFTER SOME SUGGESTION :
so now i make it like this
public class Menu_Riwayat extends Fragment {
//inisialisasi kontroller
private DBDataSource dataSource;
//inisialisasi arraylist
private ArrayList<Investasi_DB> values;
static ListView lv;
private Button button_hapus;
static LinearLayout mLinear;
#Nullable
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
mLinear = (LinearLayout) inflater.inflate(R.layout.viewdata, container, false);
lv = (ListView) mLinear.findViewById(R.id.list);
dataSource = new DBDataSource(getActivity());
// buka kontroller
dataSource.open();
// ambil semua data barang
values = dataSource.getAllInvestasi_DB();
// masukkan data barang ke array adapter
ArrayAdapter<Investasi_DB> adapter = new ArrayAdapter<Investasi_DB>(getActivity(),
android.R.layout.simple_list_item_1, values);
// set adapter pada list
lv.setAdapter(adapter);
//lv.setOnItemLongClickListener(this);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final Dialog dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.dialog_view);
dialog.setTitle("Pilihan");
dialog.show();
final Investasi_DB b = (Investasi_DB) lv.getItemAtPosition(position);
button_hapus = (Button) dialog.findViewById(R.id.button_hapus);
button_hapus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dataSource.deleteInvestasi_DB(b.getId());
dialog.dismiss();
getActivity().finish();
}
});
}
});
return mLinear;
}
its working, but the apps close itself after i click the button (i think because of getActivity().finish();), any idea about that ?
I need help to solve the error (correct way to implement it):
getListAdapter(), getIntent(), and this in
lv.setOnItemClickListener(this);
if with this you want to access a Context, you can use getActivity(). Fragment is not a Context
In setOnItemClickListener(this);, this refers to the current instance. With that line you are implying that this is also implementing the OnItemClickListener interface. Which is not true. You need yo add implement OnItemClickListener to your Fragment class.
getListAdapter():
instead of getListAdapter() you can use the ListView to retrieve the item at position, since you are already keeping a reference as member. Change
final Investasi_DB b = (Investasi_DB) getListAdapter().getItem(pos);
with
final Investasi_DB b = (Investasi_DB) lv.getItemAtPosition(pos);
why do you need this line startActivity(getIntent());?
Further to my question "Extracting multiple data items from LinkedList() element" which now works fine on the demo "Book" app thanks to quocnhat7, now I'm stuck on the onItemClick where the method getId() method causes "error: cannot find symbol method getId()" on building the app.
public class MainActivity extends ListActivity implements OnItemClickListener {
JCGSQLiteHelper db = new JCGSQLiteHelper(this);
List list;
ArrayAdapter myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db.createBook(new Book("The waves", "Virginia Woolf"));
db.createBook(new Book("Mrs Dalloway", "Virginia Woolf"));
db.createBook(new Book("War and Peace", "Leo Tolstoy"));
// get all books
List<Book> list = db.getAllBooks();
List<String> listTitle = new ArrayList<String>();
for (int i = 0; i < list.size(); i++) {
listTitle.add(i, list.get(i).getTitle());
}
myAdapter = new ArrayAdapter(this, R.layout.row_layout, R.id.listText, listTitle);
getListView().setOnItemClickListener(this);
setListAdapter(myAdapter);
}
#Override
public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) {
// start BookActivity with extras the book id
Intent intent = new Intent(this, BookActivity.class);
intent.putExtra("book", list.get(arg2).getId());
startActivityForResult(intent, 1);
}
}
You have 2 problems:
list is defined as non-generic List, thus it's get method returns an Object, and not Book, and Object doesn't have a method getId.
List<Book> list = db.getAllBooks(); hides the member List list, and so there is no assignment to the member list.
To fix it, you should do 2 things:
Change list definition:
public class MainActivity extends ListActivity implements OnItemClickListener {
JCGSQLiteHelper db = new JCGSQLiteHelper(this);
List<Book> list;
// ^^^^^^
Assign to the member, not to a local variable:
// get all Books
list = db.getAllBooks();
I am not able get onItemCickListener to work. All I am doing is opening up a fragment using intents. Please do let me know if I am doing anything fishy here ?
public class MyListFragment extends ListFragment {
private ArrayList<String> myList = null;
private ArrayAdapter<String> myAdapter;
#Override
public void onActivityCreated(Bundle savedInstanceState){
Log.d("Example:", "In Fragement Calss");
super.onActivityCreated(savedInstanceState);
Resources myResources = getResources();
myList = new ArrayList<String>(Arrays.asList(myResources.getStringArray(R.array.myExamArray)));
myAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,myList);
setListAdapter(myAdapter);
ListView lv = (ListView) getActivity().findViewById(R.id.listView);
lv.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent myIntent = new Intent(view.getContext(), DetailsFragment.class);
startActivity(myIntent);
}
});
}
}
Note that the ListView blocks clicks of an item that contains at least one focusable
descendant but it doesn’t make the content focus-reachable calling
setItemsCanFocus(true). One workaround is by disabling focusability of descendants, using
android:descendantFocusability="blocksDescendants"
in the layout defining your list item. (First learned of this myself from http://cyrilmottier.com/2011/11/23/listview-tips-tricks-4-add-several-clickable-areas/, but a few other SO posts also point this out.) Does your layout contain buttons? If so, you'd fall into this case.
I don't see where you are inflating a specific XML for this Fragment... but it is possible you are referencing the wrong ListView.
Regardless you should use the existing onListItemClick method:
public class MyListFragment extends ListFragment {
private ArrayList<String> myList = null;
private ArrayAdapter<String> myAdapter;
#Override
public void onActivityCreated(Bundle savedInstanceState){
// Remove the OnItemClickListener, but keep everything else
}
#Override
public void onListItemClick (ListView l, View v, int position, long id) {
Intent myIntent = new Intent(this, DetailsFragment.class);
startActivity(myIntent);
}
}