I am an extreme beginner at Android Studio and using JavaScript, so still learning and trying to grasp new concepts of android studio as a whole.
I am trying to create a database where it adds, edits and deletes records that a user manually inputs.
When I get to my friends.xml page (friends.java) and fill out the fields to add a user and press "ADD" it comes up with my toast to notify the user the data has been added succesfully however when I click on "VIEW DATA" (which links to view_data.xml (listdata.java)) it doesn't seem to show the entries.
It would be great if the answer would be put as simply as possible as I am still a beginner! Any help will be greatly appreciated! Thanks!
friends.java
package com.example.chris.mobileappsassignment;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class friends extends AppCompatActivity {
EditText firstnameinput, lastnameinput, ageinput, addressinput;
Button addbutton, viewbutton;
DatabaseHelper dbhlpr;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_friends);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
firstnameinput = (EditText) findViewById(R.id.firstnameinput);
lastnameinput = (EditText) findViewById(R.id.lastnameinput);
ageinput = (EditText) findViewById(R.id.ageinput);
addressinput = (EditText) findViewById(R.id.addressinput);
addbutton = (Button) findViewById(R.id.addbutton);
viewbutton = (Button) findViewById(R.id.viewbutton);
dbhlpr = new DatabaseHelper(this);
addbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean addOK = true;
int age_as_int = -1;
String firstName = firstnameinput.getText().toString();
String lastName = lastnameinput.getText().toString();
String age = ageinput.getText().toString();
String address = addressinput.getText().toString();
if (firstName.length() < 1) {
toastMessage("You must enter something in this field!");
firstnameinput.requestFocus();
addOK = false;
}
if (lastName.length() < 1) {
toastMessage("You must enter something in this field!");
lastnameinput.requestFocus();
addOK = false;
}
if (age.length() < 1) {
toastMessage("You must enter something in this field!");
ageinput.requestFocus();
addOK = false;
}
if (address.length() < 1) {
toastMessage("You must enter something in this field!");
addressinput.requestFocus();
addOK = false;
}
try {
age_as_int = Integer.parseInt(age);
} catch (NumberFormatException e) {
toastMessage("You must enter a valid Number in this field!");
ageinput.requestFocus();
addOK = false;
}
if (addOK) {
dbhlpr.addData(firstName,lastName,"????",age_as_int,address);
toastMessage("Friend Added!");
}
}
});
viewbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context,listdata.class);
startActivity(intent);
}
});
} //END ON CREATE CLASS
//TOAST MSSG
private void toastMessage(String message) {
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_friends, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
listdata.java
package com.example.chris.mobileappsassignment;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import static com.example.chris.mobileappsassignment.R.layout.view_data;
public class listdata extends AppCompatActivity {
private static final String TAG = "listdata";
DatabaseHelper mDatabaseHelper;
private ListView mListView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(view_data);
mListView = (ListView) findViewById(R.id.ListView);
mDatabaseHelper = new DatabaseHelper(this);
populateListView();
} //END ONCREATE
private void populateListView() {
Log.d(TAG, "populate ListView: Displaying Data in the ListView");
//get data and append to list
Cursor data = mDatabaseHelper.getData();
Log.d("CURSORCOUNT", "Number of rows in Cursor =");
Integer.toString(data.getCount());
ArrayList<String> listData = new ArrayList<>();
while(data.moveToNext()){
//GET VALUE FROM DB IN COL1
//then add to ArrayList
listData.add(data.getString(1));
listData.add(data.getString(2));
listData.add(data.getString(3));
listData.add(data.getString(4));
listData.add(data.getString(5)); // NUMBERS REFER TO COL'S. (coloumns)
}
//create LIST ADAPTER AND SET ADAPTER
ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listData);
mListView.setAdapter(adapter);
//set on onclick listener to list view
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String name = adapterView.getItemAtPosition(position).toString(); // will grab object and convert to string
Log.d(TAG, "onItemClick: You clicked on " + name);
Cursor data = mDatabaseHelper.getItemID(name); // get ID associated with that name
int itemID = 1; // WHEN SEARCHING // RETURN SOMETHING THAT EXISTS
while (data.moveToNext()){
itemID = data.getInt(0); // if data is returned
}
if (itemID > -1) {
Log.d(TAG, "onItemClick: The ID is: " + itemID);
Intent editScreenIntent = new Intent(listdata.this, EditDataActivity.class ); // VID2, 2.49
editScreenIntent.putExtra("id", itemID);
editScreenIntent.putExtra("name", name);
startActivity(editScreenIntent);
}
else {
toastMessage("No ID is associated with that name");
}
}
});
}
/**
* customizable toast
*/
private void toastMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
} //END CLASS
ERROR in logcat when pressing "ADD"
--------- beginning of crash
09-12 02:40:00.329 26615-26615/com.example.chris.mobileappsassignment E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chris.mobileappsassignment, PID: 26615
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ComponentName.<init>(ComponentName.java:128)
at android.content.Intent.<init>(Intent.java:4449)
at com.example.chris.mobileappsassignment.friends$2.onClick(friends.java:99)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
The issue here is that the column called address couldn't be found in the table named friends_table this is as per :-
09-10 20:38:48.892 10003-10003/com.example.chris.mobileappsassignment E/SQLiteDatabase: Error inserting address=Mike lastname=Mike firstname=Mike age=Mike malefemale=Mike
android.database.sqlite.SQLiteException: table friends_table has no column named address (code 1): , while compiling: INSERT INTO friends_table(address,lastname,firstname,age,malefemale) VALUES (?,?,?,?,?)
It is likely that the definition used to create the table needs to be changed or that the definition has been changed but that it has been implemented because the database's onCreate method has not been run.
The onCreate method only runs automatically when the database itself is created, that being once for the lifetime of the database file. There are 3 easy ways to get onCreate to run, noting that ALL 3 WILL DELETE ANY EXISTING DATA IN THE DATABASE.
Uninstall the App.
Clear the App's Data.
If the onUpgrade method drops the respective table or tables AND it calls onCreate then the verion number of the database can be incremented.
As such you need to
a) Ensure that your table definition includes the address column (and also columns lastname, firstname, age and malefemale)
b) get onCreate to run by 1 of the three methods above (there are other ways around the issue for those who want need to retain the existing data).
Again, from the log, it is likely you have an issue with how you prepare the data within the addData as you are trying to insert the same data into all columns e.g. Error inserting address=Mike lastname=Mike firstname=Mike age=Mike malefemale=Mike would result in lastname, firstname, age, malefemale all having the value Mike (sheesh I didn't know I was that popular :))
Looking at your friends class you use (as one example):-
if (firstnameinput.length() !=0) {
AddData(firstName);
firstnameinput.setText(""); .........
You are passing a single paremeter to the AddData method, so it is likely that this one parameter is being used as the data to populate all of the columns.
As such you probably want to change the AddData method to accept 5 parameters (address, lastname, firstname, age and malefemale) and then to populate the columns with the respective data.
Additionally you then subsequently call AddData a number of times (4) for each data item (except malefemale). This will result in 4 rows being added per click of the add button. I believe that what you really want is for one row to be added as such you should only call AddData once with all 5 or 4 (perhaps you haven't got to malefemale as yet) data items. Thus you will end up with one row with all the respective data.
Edit after adding data was reported as working.
As you're having so many problems, many of which appear to be coming from pre-existing code. So it appears that much of the code is untested. I'd suggest a different approach. basically concentrate on getting something working and then add to this.
As such here's working code (pretty basic) that works and allows you to a) Add friends (bar gender as you'd probably want to select this) and b) list them via the view button.
First AndroidManifest.xml (NOTE! only use this for comparison if needed)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mjt.so46145559friendsdb">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".friends">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".listdata"></activity>
</application>
</manifest>
activity_friends.xml The layout for the friends activity (very basic with no spinner) :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mjt.so46145559friendsdb.friends">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
<EditText
android:id="#+id/firstnameinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="firstname"
android:inputType="text"/>
<EditText
android:id="#+id/lastnameinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="lastname"
android:inputType="text"/>
<EditText
android:id="#+id/ageinput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="3"
android:inputType="number"/>
<EditText
android:id="#+id/addressinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="address"
android:inputType="text"/>
<Button
android:id="#+id/addbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ADD"/>
<Button
android:id="#+id/viewbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="VIEW"/>
</LinearLayout>
Note! it might well be that you existing layout works.
activity_listdata.xml The layout for listdata activity invoked when the VIEW button is clicked (extremely basic).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/friendslist_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/friendlist"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
</LinearLayout>
listdataitem.xml the layout used for each item (row) displayed by the ListView in the listdata activity.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/firstnamedisplay"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
<TextView
android:id="#+id/lastnamedisplay"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
<TextView
android:id="#+id/agedisplay"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<TextView
android:id="#+id/addressdisplay"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="match_parent" />
</LinearLayout>
DatabaseHelper.java The SQLiteOpenHelper subclass, note some changes have been made (brownie points available for spotting them :))
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DatabaseHelper";
public static final String TABLE_NAME = "friends_table";
public static final String IDCOL = "_id";
public static final String COL1 = "firstname";
public static final String COL2 = "lastname";
public static final String COL3 = "malefemale";
public static final String COL4 = "age";
public static final String COL5 = "address";
public DatabaseHelper (Context context) {
super(context, TABLE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (" + IDCOL+ " TEXT PRIMARY KEY, " +
COL1 + " TEXT, " +
COL2 + " TEXT, " +
COL3 + " TEXT, " +
COL4 + " INTEGER, " +
COL5 + " TEXT " +
")";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP IF TABLE EXISTS" + TABLE_NAME);
onCreate(db);
}
public boolean addData(String firstname, String lastname, String gender, int age, String address) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL1, firstname);
contentValues.put(COL2, lastname);
contentValues.put(COL3, gender);
contentValues.put(COL4, age);
contentValues.put(COL5, address);
long result = db.insert(TABLE_NAME, null, contentValues);
//if data as inserted inorrectly it will return -1
if (result == 1)
return false;
else {
return true;
}
}
/**
* Returns all data from DB
*/
public Cursor getData() {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
return db.query(TABLE_NAME,null,null,null,null,null,null);
}
/**
* Returns ID that matches the name
* searches the DB and returns the ID associated with that name
*/
public Cursor getItemID(String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COL1 + " FROM " + TABLE_NAME + // SELECT ID FROM DB
" WHERE " + COL2 + " = '" + name + "'"; // WHERE THE LAST NAME = NAME SELECTED
Cursor data = db.rawQuery(query, null);
return data;
}
/**
* Alternative means of getting ID return it as a long rather in a cursor
*/
public long getID(String firstname) {
long rv = 0;
SQLiteDatabase db = this.getWritableDatabase();
Cursor csr = db.query(TABLE_NAME,null,COL2 + "=?",new String[]{firstname},null,null,null);
if (csr.moveToFirst()) {
rv = csr.getLong(csr.getColumnIndex(IDCOL));
}
csr.close();
return rv;
}
/**
* UPDATES THE NAME
*
* UPDATE TABLE > SET LASTNNAME(COL2) = newName = WHERE id = id in Question = AND LASTNAME(COL2) = oldName (was previously) >
*/
public void updateName (String newName, int id, String oldName) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TABLE_NAME + " SET " + COL2 +
" = '" + newName + "' WHERE " + COL1 + " = '" + id + "'" +
" AND " + COL2 + " = '" + oldName + "'";
//LOGS THE NEW NAME
Log.d(TAG, "updateName: query: " + query);
Log.d(TAG, "updateName: Setting name to " + newName); // NEW NAME CHANGING IT TO
db.execSQL(query); // EXECUTE QUERY
}
/**
* DELETE FROM DATABASE
* >>> DELETE FROM TABLE WHERE id = id passed AND name = name passed
*
*/
public void deleteName(int id, String name){
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + TABLE_NAME + " WHERE "
+ COL1 + " = '" + id + "'" +
" AND " + COL2 + " = '" + name + "'";
Log.d(TAG, "deleteName: query: " + query);
Log.d(TAG, "deleteName: Deleting " + name + " from database.");
db.execSQL(query); // EXECUTE QUERY
}
}
friends.java (bare bones but it works, prettifying is up to you :))
public class friends extends AppCompatActivity {
EditText firstnameinput, lastnameinput, ageinput, addressinput;
Button addbutton, viewbutton;
DatabaseHelper dbhlpr;
Context context; //############### FIX_001
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_friends);
context = this; //########## FIX_001
firstnameinput = (EditText) findViewById(R.id.firstnameinput);
lastnameinput = (EditText) findViewById(R.id.lastnameinput);
ageinput = (EditText) findViewById(R.id.ageinput);
addressinput = (EditText) findViewById(R.id.addressinput);
addbutton = (Button) findViewById(R.id.addbutton);
viewbutton = (Button) findViewById(R.id.viewbutton);
dbhlpr = new DatabaseHelper(this);
addbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean addOK = true;
int age_as_int = -1;
String firstName = firstnameinput.getText().toString();
String lastName = lastnameinput.getText().toString();
String age = ageinput.getText().toString();
String address = addressinput.getText().toString();
if (firstName.length() < 1) {
toastMessage("You must enter something in this field!");
firstnameinput.requestFocus();
addOK = false;
}
if (lastName.length() < 1) {
toastMessage("You must enter something in this field!");
lastnameinput.requestFocus();
addOK = false;
}
if (age.length() < 1) {
toastMessage("You must enter something in this field!");
ageinput.requestFocus();
addOK = false;
}
if (address.length() < 1) {
toastMessage("You must enter something in this field!");
addressinput.requestFocus();
addOK = false;
}
try {
age_as_int = Integer.parseInt(age);
} catch (NumberFormatException e) {
toastMessage("You must enter a valid Number in this field!");
ageinput.requestFocus();
addOK = false;
}
if (addOK) {
dbhlpr.addData(firstName,lastName,"????",age_as_int,address);
toastMessage("Friend Added!");
}
}
});
viewbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context,listdata.class); //########## FIX_001
startActivity(intent);
}
});
}
private void toastMessage(String message) {
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
}
Finally a cheap and cheerful listdata.java
public class listdata extends AppCompatActivity {
ListView mListView;
TextView firstname, lastname, age, address;
DatabaseHelper dbhlpr;
Cursor friendlist;
SimpleCursorAdapter sca;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listdata);
mListView = (ListView) findViewById(R.id.friendlist);
firstname = (TextView) findViewById(R.id.firstnamedisplay);
lastname = (TextView) findViewById(R.id.lastnamedisplay);
age = (TextView) findViewById(R.id.agedisplay);
address = (TextView) findViewById(R.id.addressdisplay);
dbhlpr = new DatabaseHelper(this);
friendlist = dbhlpr.getData();
Log.d("CURSORCOUNT","Rows in Cursor is " + friendlist.getCount());
// make a list of the columns from which the data is to be extracted
String[] dbcolums = {
DatabaseHelper.COL1,
DatabaseHelper.COL2,
DatabaseHelper.COL4,
DatabaseHelper.COL5
};
// make a list of the view's id where the data is to be placed
//Note each column will have a respective view
int[] listviewids = {R.id.firstnamedisplay, R.id.lastnamedisplay, R.id.agedisplay, R.id.addressdisplay};
// Setup the Adapter
sca = new SimpleCursorAdapter(
this, // The context
R.layout.listdataitem, // the lasyout for an item
friendlist, // cursor with data
dbcolums, // the list of DB columns to get data from
listviewids, // the views in the layout where to place the data
0 // don't worry
);
// Finally tie the adapter to the ListView
mListView.setAdapter(sca);
}
}
take these, perhaps even start a new project, AS THEY ARE, get it working and then add small bits at a time. Create new questions when you have problems. Please do not amend questions removing stuff that you've added basically only add to a question asked. (very confusing with bits going). Also always make it very clear what has been added.
It works as per :-
a) When first started :-
b) Adding data :-
c) View :-
Related
I need to implement "Edit->Find" function for a WebView2 UI Component using WPF/C#/javascript... Below you will find two examples: One that is made for a TextBox UI Control called MainWindow1, and the other that is implemented for a WebView2 UI Control that is called MainWindows2. I'm giving both examples because I need to work the same way for each one. The TextBox example is working, but the WebView2 example is missing some javascript code to finish it and maybe requires some tweeting of the C# calls to WebView2.
First, I implemented a "Find Forward" button for a TextBox that I can click multiple times to find the next string matching the search pattern in the textbox. And Here's my XML and C# for it:
MainWindow1 GUI:
MainWindow1 XML:
<Window x:Class="WpfApp1.MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Loaded="Window_Loaded"
Title="MainWindow1" Height="450" Width="800">
<DockPanel LastChildFill="True">
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top" Background="Aqua">
<TextBox Name="TboxFind" Width="80" Text="id"/>
<Button Name="FindForward" Content="FindForward"
Click="FindForward_Click"/>
</StackPanel>
<TextBox Name="textbox1" VerticalScrollBarVisibility="Auto"/>
</DockPanel>
</Window>
MainWindow1 C#:
using System.Text.RegularExpressions;
using System.Windows; using System.Windows.Controls;
namespace WpfApp1 {
public partial class MainWindow1 : Window {
public MainWindow1() {InitializeComponent();}
private void Window_Loaded(object sender, RoutedEventArgs e) {
string text1 = "";
for (int i = 0; i < 10000; i++) {
text1 = text1 + "id" + i.ToString() + "\n";}
textbox1.Text = text1;textbox1.Focus();textbox1.CaretIndex = 0;
}
private void TextBoxGotoLine(TextBox textbox1, int linenum) {
var target_cpos
= textbox1.GetCharacterIndexFromLineIndex(linenum);
var target_char_rect
= textbox1.GetRectFromCharacterIndex(target_cpos);
var first_char_rect = textbox1.GetRectFromCharacterIndex(0);
textbox1.ScrollToVerticalOffset(target_char_rect.Top
- first_char_rect.Top);
}
private void FindForward_Click(object sender, RoutedEventArgs e) {
string pattern = #"(?i)(" + Regex.Escape(TboxFind.Text) + #")";
string text1 = textbox1.Text.Substring(
textbox1.CaretIndex + textbox1.SelectionLength);
var match1 = Regex.Match(text1, pattern);
if (match1.Success) {
textbox1.Focus();
textbox1.Select(textbox1.CaretIndex
+ textbox1.SelectionLength
+ match1.Index, match1.Groups[0].Length);
} //if
} //function
}/*class*/ }/*namespace*/
The problem I'm having is that I also need this same feature for a WebView2 UI Control.
So I install the WebView2 UI Control:
WebView2 Install:
PM > Install-Package Microsoft.Web.WebView2
Add to XML: xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
using Microsoft.Web.WebView2.Core;
And here's my corresponding XML and C# demo code that should work the same as the first example I have given:
MainWindow2 GUI:
MainWindows2 XML:
<Window x:Class="WpfApp1.MainWindow2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wv2
="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Loaded="Window_Loaded"
Title="MainWindow2" Height="450" Width="800" >
<DockPanel LastChildFill="True">
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top" Background="Aqua">
<TextBox Name="SearchStr" Width="80" Text="id"/>
<Button Name="FindForward"
Content="FindForward" Click="FindForward_Click"/>
</StackPanel>
<wv2:WebView2 Name="webview2" CoreWebView2InitializationCompleted
="webview2_CoreWebView2InitializationCompleted" />
</DockPanel>
</Window>
MainWindow2 C#:
using System.Windows; using System.Threading;
using Microsoft.Web.WebView2.Core;
namespace WpfApp1 {
public partial class MainWindow2 : Window {
public MainWindow2() {InitializeComponent(); SearchStr.Focus(); }
private async void Window_Loaded(object sender, RoutedEventArgs e) {
await webview2.EnsureCoreWebView2Async();
}
private void webview2_CoreWebView2InitializationCompleted(
object sender, CoreWebView2InitializationCompletedEventArgs e)
{
string html = "";
for (int i = 0; i < 100; i++) {
string id = "id" + i.ToString();
html = html + "<b>" + id + "</b><br/>";
}
webview2.CoreWebView2.NavigateToString(html);
}
private async Tasks.Task<string> Find(string pattern) {
string js = "";
js = js + "var m1 = document.getElementById(""body"")";
js = js + "/*... ??? what goes here ??? */";
// Find and highlight one at a time, and scroll into view ...
// repeat find from beginning of html body when done ...
// See MainWindow1 example with TextBox for desired behavior here.
return await webview2.ExecuteScriptAsync(js);
}
private void async FindForward_Click(object s, RoutedEventArgs e) {
await Find(SearchStr.Text);
}
}/*class*/ }/*namespace*/
How to use WebBrowser UI Control to do a:
Menu->Edit->Find "SearchStr1"
When I click FindForward Button? I'm thinking it has something to do with executing Javascript on the DOM? each time the button is pressed?
Good evening, I am creating an application and I need help with this error.
the
log cat of the error:java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at cqdevelopers.incrediblediet.Fragment3.getAddressKeyValueFile(Fragment3.java:90)
at cqdevelopers.incrediblediet.Fragment3.onCreateView(Fragment3.java:25)
<!-- begin snippet: js hide: false -->
<!-- language: lang-js -->
05-16 02:25:21.711 6498-6498/cqdevelopers.incrediblediet E/AndroidRuntime: FATAL EXCEPTION: main
Process: cqdevelopers.incrediblediet, PID: 6498
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at cqdevelopers.incrediblediet.Fragment3.getAddressKeyValueFile(Fragment3.java:90)
at cqdevelopers.incrediblediet.Fragment3.onCreateView(Fragment3.java:25)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1177)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1025)
at android.support.v4.view.ViewPager$3.run(ViewPager.java:254)
at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1920)
at android.support.v4.view.ViewPager.onInterceptTouchEvent(ViewPager.java:2050)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2108)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2403)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1737)
at android.app.Activity.dispatchTouchEvent(Activity.java:2765)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2364)
at android.view.View.dispatchPointerEvent(View.java:9514)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4230)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4096)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3787)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3844)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5922)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5896)
at android.view.
Fragment3.java:
public class Fragment3 extends Fragment {
private EditText editText;
private TextView textView;
private Button button;
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment3_layout, container, false);
getAddressKeyValueFile();
editText = (EditText) v.findViewById(R.id.tvadress);
textView = (TextView) v.findViewById(R.id.textView);
button = (Button) v.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String address = null;
address = editText.getText().toString();
textView.setText(address);
setAddressKeyValueFile(address);
}
});
return v;
}
private void getAddressKeyValue() {
SharedPreferences sharedPreferences = this.getActivity().getSharedPreferences("r", Context.MODE_PRIVATE);
String key = getString(R.string.address);
String existingAddress = sharedPreferences.getString(key, null);
if (existingAddress != null) {
TextView textView = (TextView) getActivity().findViewById(R.id.textView);
textView.setText(existingAddress);
}
}
private void setAddressKeyValue(String address)
{
SharedPreferences sharedPreferences = this.getActivity().getSharedPreferences("d" ,Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
String key = getString(R.string.address);
editor.putString(key,address);
editor.commit();
}
private void getAddressKeyValueFile()
{
Context context = getContext().getApplicationContext();
String fileName = getString(R.string.filename);
SharedPreferences sharedPreferences = context.getSharedPreferences(fileName,Context.MODE_PRIVATE);
String key = getString(R.string.address);
String existingAddress = sharedPreferences.getString(key,null);
if(existingAddress != null)
{
TextView textView = (TextView) getActivity().findViewById(R.id.textView);
textView.setText(existingAddress);
}
}
private void setAddressKeyValueFile(String address)
{
Context context = getContext().getApplicationContext();
String fileName = getString(R.string.filename);
SharedPreferences sharedPreferences = context.getSharedPreferences(fileName,Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
String key = getString(R.string.address);
editor.putString(key, address);
editor.commit();
}
}
And fragment3.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="cqdevelopers.incrediblediet.MainActivity$PlaceholderFragment">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tvadress"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="register"
android:id="#+id/textView2"
android:layout_marginTop="23dp"
android:layout_below="#+id/button"
android:layout_centerHorizontal="true" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button"
android:layout_below="#+id/tvadress"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="#+id/textView"
android:layout_marginTop="29dp"
android:layout_below="#+id/textView2"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Kindly have a look on exception and let me know where i am doing wrong, your help is appreciated thanks in Advance.
change position of getAddressKeyValueFile
//getAddressKeyValueFile();
editText = (EditText) v.findViewById(R.id.tvadress);
textView = (TextView) v.findViewById(R.id.textView);
getAddressKeyValueFile();
and delete line:
TextView textView = (TextView) getActivity().findViewById(R.id.textView);
in getAddressKeyValueFile()
This line of code textView = (TextView) v.findViewById(R.id.textView); is trying to get the TexView with the id textView from the activity's layout not from the fragment's layout.
You should change:
TextView textView = (TextView) getActivity().findViewById(R.id.textView);
textView.setText(existingAddress);
to:
if(textView!=null){
textView.setText(existingAddress);
}
in both the getAddressKeyValueFile() and getAddressKeyValue() methods.
Also, in the onCreateView(...) method, call getAddressKeyValueFile(); only after textView has been initialized.
in the getAddressValueFile, change the way the strings are retrived.
private void getAddressKeyValueFile()
{
Context context = getContext().getApplicationContext();
String fileName = getResources.getString(R.string.filename);
SharedPreferences sharedPreferences = context.getSharedPreferences(fileName,Context.MODE_PRIVATE);
String key = getResources.getString(R.string.address);
String existingAddress = sharedPreferences.getString(key,null);
if(existingAddress != null)
{
TextView textView = (TextView) getActivity().findViewById(R.id.textView);
textView.setText(existingAddress);
}
}
instead of
getString(R.string.filename)
change to
getResources.getString(R.string.filename)
Also, make similar changes in the setAddressKeyValue method.
how can i intent back from (activity1-> fragment1) actually my design concept is like ( fragment1-> activity1-> fragment1) in fragment1 i click the data it bring me to activity1 for edit purpose or either update the data or remove the data after click either both button it will bring me back to the fragment1 and look the overall data but my problem is i click either both button it will jump out from the app, how can i solve this problem? using intent or ?
the code below is Update_detail_info ( activity1 )
public class Update_detail_info extends AppCompatActivity implements View.OnClickListener {
EditText weight,bodyf,timef,datef,commentf;
Button btnUpdate, btnRemove;
long weight_id;
SQLControlerWeight dbcon;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_detail_info);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
dbcon = new SQLControlerWeight(this);
dbcon.openDatabase();
btnUpdate = (Button) findViewById(R.id.button_update);
btnRemove = (Button) findViewById(R.id.button_remove);
Intent i = getIntent();
String weightID = i.getStringExtra("weightId");
String dN = i.getStringExtra("dateNum");
String tN = i.getStringExtra("timeNum");
String wN = i.getStringExtra("weightNum");
String bN = i.getStringExtra("bodyFatNum");
String cM = i.getStringExtra("comment");
weight_id = Long.parseLong(weightID);
datef.setText(dN);
timef.setText(tN);
weight.setText(wN);
bodyf.setText(bN);
commentf.setText(cM);
btnUpdate.setOnClickListener(this);
btnRemove.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_update:
String d_update = datef.getText().toString();
String t_update = timef.getText().toString();
String w_update = weight.getText().toString();
String b_update = bodyf.getText().toString();
String c_update = commentf.getText().toString();
dbcon.updateNote(weight_id,w_update,b_update,d_update,t_update,c_update);
this.returnHome();
break;
case R.id.button_remove:
dbcon.deleteNote(weight_id);
this.returnHome();
break;
}
}
public void returnHome() { // is that here the code are wrong ? cause i need to jump back to the previous fragment1
Intent home_intent = new Intent(getApplicationContext(),
HistoryF.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(home_intent);
}
}
break;
}
code below is the fragment for HistoryF ( fragment1)
public class HistoryF extends Fragment {
View contentView;
ListView list;
SQLControlerWeight dbconnection;
TextView weight_num, date_num, time_num, bf_num, comment,weight_ID;
private SimpleCursorAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
contentView = inflater.inflate(R.layout.history_fragment, container, false);
dbconnection = new SQLControlerWeight(getActivity());
dbconnection.openDatabase();
list = (ListView) contentView.findViewById(R.id.listViewWeight);
Cursor cursor = dbconnection.readNote();
String[] from = new String[]{
DBHelperNote.WEIGHT_ID,
DBHelperNote.WEIGHT_NUM,
DBHelperNote.BODY_FAT,
DBHelperNote.WEIGHT_DATE,
DBHelperNote.WEIGHT_TIME,
DBHelperNote.WEIGHT_COMMENTS
};
int[] to = new int[]{
R.id.weight_id,
R.id.weight_num,
R.id.bf_num,
R.id.date_num,
R.id.time_num,
R.id.comment_text
};
adapter = new SimpleCursorAdapter(
contentView.getContext(), R.layout.history, cursor, from, to,0);
adapter.notifyDataSetChanged();
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
weight_ID = (TextView) view.findViewById(R.id.weight_id);
weight_num = (TextView) view.findViewById(R.id.weight_num);
bf_num = (TextView) view.findViewById(R.id.bf_num);
date_num = (TextView) view.findViewById(R.id.date_num);
time_num = (TextView) view.findViewById(R.id.time_num);
comment = (TextView) view.findViewById(R.id.comment_text);
String weightId = weight_ID.getText().toString();
String wn = weight_num.getText().toString();
String bfn = bf_num.getText().toString();
String dn = date_num.getText().toString();
String tn = time_num.getText().toString();
String cm = comment.getText().toString();
Intent modify_intent = new Intent(getActivity(), Update_detail_info.class);
modify_intent.putExtra("weightId", weightId);
modify_intent.putExtra("dateNum", dn);
modify_intent.putExtra("timeNum", tn);
modify_intent.putExtra("weightNum", wn);
modify_intent.putExtra("bodyFatNum", bfn);
modify_intent.putExtra("comment", cm);
startActivity(modify_intent);
}
});
return contentView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
this is my main activity for control the tab
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new KeyInWeightF(), "TRACK");
adapter.addFragment(new HistoryF(), "HISTORY");
adapter.addFragment(new AnalysisF(), "GRAPH");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
You can simply use this code on your returnHome()
Intent intent = NavUtils.getParentActivityIntent(Update_detail_info.this); //get parent activity
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
NavUtils.navigateUpTo(Update_detail_info.this, intent); // and then navigate it to parent
or
NavUtils.navigateUpFromSameTask(Update_detail_info.this);
both worked same
and in your manifest file define parentActivity
manifest.xml
<activity
android:name="com.example.yourApp.MainActivity" ...>
...
</activity>
<!-- A child of the main activity -->
<activity
android:name="com.example.yourApp.Update_detail_info"
android:label="#string/title_activity_Update_detail"
android:parentActivityName="com.example.yourApp.MainActivity" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.yourApp.MainActivity" />
</activity>
For more details to Providing Up Navigation go to this link.
And for understand startactivityforresult go to this link
I have drawn a customized navigation drawer with ListView and header but when i scroll the List the checkbox in the List are getting unchecked.
Secondly when i click on the reset button in the header part I want that all the checkbox in the Listview should get get unchecked. I have been trying this to get it working but unable to find any solution..
The snippets are
public class NavigationDrawer extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.filter_navigation_drawer, container,false);
drawerListView= ( ListView ) view.findViewById( R.id.listDrawer );
drawerListView.setOnItemClickListener(new FilterDrawerItemClickListener());
dataList.add(new FilterDrawerItem("sample1",true));
dataList.add(new FilterDrawerItem("sample2",true));
dataList.add(new FilterDrawerItem("sample3",true));
dataList.add(new FilterDrawerItem("sample4",true));
dataList.add(new FilterDrawerItem("sample5",true));
dataList.add(new FilterDrawerItem("sample2",true));
dataList.add(new FilterDrawerItem("sample2",true));
dataList.add(new FilterDrawerItem("sample2",true));
dataList.add(new FilterDrawerItem("sample2",true));
adapter = new FilterCustomDrawerAdapter(getActivity(), R.layout.drawer_filter,dataList,drawerStatus);
drawerListView.setAdapter(adapter);
adapter.getFilterList();
resetBtn = (TextView)view.findViewById(R.id.filterby_reset);
if(resetBtn != null){
resetBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
application.setFilterStatus("reset");
for(int i=0; i<dataList.size(); i++){
dataList.get(i).setCheckBoxId(false);
}
adapter.notifyDataSetChanged();
// this.onCreateView();
}
});
}
return view;
}
}
FilterCustomDrawerAdapter.java
public class FilterCustomDrawerAdapter extends ArrayAdapter<FilterDrawerItem> {
Context context;
List<FilterDrawerItem> drawerItemList;
int layoutResID;
int item = 0;
String status;
List<Integer> filterList = new ArrayList<Integer>();
DrawerStatus drawerStatus;
StataApplication application = StataApplication.getInstance();
HashMap<Integer, Boolean> checked; // newly added code
public FilterCustomDrawerAdapter(Context context, int layoutResourceID,
List<FilterDrawerItem> listItems,DrawerStatus drawerStatus) {
super(context, layoutResourceID, listItems);
this.context = context;
this.drawerItemList = listItems;
this.layoutResID = layoutResourceID;
this.drawerStatus = drawerStatus;
checked = new HashMap<Integer, Boolean>(getCount());
}
public FilterCustomDrawerAdapter(Context context, int layoutResourceID,
List<FilterDrawerItem> listItems) {
super(context, layoutResourceID, listItems);
this.context = context;
this.drawerItemList = listItems;
this.layoutResID = layoutResourceID;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final FilterDrawerItemHolder drawerHolder;
View view = convertView;
if (view == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
drawerHolder = new FilterDrawerItemHolder();
view = inflater.inflate(layoutResID, parent, false);
drawerHolder.ItemName = (TextView) view.findViewById(R.id.drawer_filterName);
drawerHolder.checkBox = (CheckBox) view.findViewById(R.id.drawer_cbox);
view.setTag(drawerHolder);
} else {
drawerHolder = (FilterDrawerItemHolder) view.getTag();
}
FilterDrawerItem dItem = (FilterDrawerItem) this.drawerItemList.get(position);
drawerHolder.ItemName.setText(dItem.getItemName());
TextView resetView = (TextView)view.findViewById(R.id.filterby_reset);
CheckBox checkBox = (CheckBox) view.findViewById(R.id.drawer_cbox);
// Newly added code
Boolean isChecked = checked.get(position);
checkBox.setChecked(isChecked == null ? false : isChecked);
// if(application.getFilterStatus() != null) {
if(checkBox.isChecked()){
drawerHolder.checkBox.setChecked(false);
}
// }
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
if (isChecked) {
filterList.add(new Integer(position));
checked.put(position, true);
} else {
filterList.remove(new Integer(position));
checked.put(position, false);
}
}
});
drawerHolder.checkBox.setTag(position);
Log.d("FILTER_LIST_SIZE",String.valueOf(filterList.size()));
return view;
}
private static class FilterDrawerItemHolder {
TextView ItemName;
CheckBox checkBox;
}
public List<Integer> getFilterList(){
return filterList;
}
}
In the image below when I scroll the list and if i make the checkbox sample1 and sample 2 checked it becomes unchecked on scrolling.
and also on clicking reset button in the header i want all my checkbox to be unchecked..
Not able to get this working ...
UPDATE 1
resetBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
List<FilterDrawerItem> adapterDataList = adapter.getDrawerItemList();
for(int i=0; i<adapterDataList.size(); i++){ // At this place i am getting the size as 9
adapterDataList.get(i).setCheckBoxId(false);
}
adapter.setDrawerItemList(adapterDataList);
adapter.notifyDataSetChanged();
}
});
In your FilterDrawerItem class, make a boolean variable isChecked.
Now in your adapter class, write something like this:
if(dItem.isChecked){
drawerHolder.checkBox.setChecked(true);
}
else{
drawerHolder.checkBox.setChecked(false);
}
and in your OnCheckedChangeListener:
if (isChecked) {
//your other code
dItem.setChecked(true);
notifyDataSetChanged();
} else {
//your other code
dItem.setChecked(false);
notifyDataSetChanged();
}
#Orest Savchak's answer is also right, but keeping track of checkboxes in your POJO classes will help you to retrieve the checked items later and also do other things easier, like you want to uncheck all the checkboxes on click of "Reset" button. For that, in onClick() on reset button, you'll just need to do:
for(int i=0; i<FilterDrawerItem.size; i++){
FilterDrawerItem.get(i).setChecked(false);
}
adapterObject.notifyDataSetChanged();
EDIT 1:
Create getter setter for drawerItemList in your adapter and then in onClick() of reset button, in place of dataList, do as following:
List<FilterDrawerItem> adapterDataList=adapter.getDataList();
for(int i=0; i<adapterDataList.size(); i++){
adapterDataList.get(i).setCheckBoxId(false);
}
adapter.setDataList(adapterDataList);
adapter.notifyDataSetChanged();
It because of recycling use of views in ListView. You should create some HashMap:
HashMap<Integer, Boolean> checked;
Then in your constructor do this:
checked = new HashMap<Integer, Boolean>(getCount());
After set OnCheckedChangeListener on your checkboxes, and in event method do this:
checked.put(position, yourCheckBoxCheckedState);
And in getView() method do this:
Boolean isChecked = checked.get(position);
checkBox.setChecked(isChecked == null ? false : isChecked)
Try this, I think it should help
UPDATE
resetBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
adapter.deselectAll();
}
});
Then in adapter create method:
public void deselectAll() {
checked = new HashMap<Integer, Boolean>(getCount());
notifyDataSetChanged();
}
Here is my requirement :
I'am loading one html file on to a WebView. I have a button in html file to select the date. When i click on that button i want to open android date picker dialog. And after selecting the date, i want to display the selected date in html file. Can anyone guide me. please.
HTML :
<input type="button" value="Select Date" onClick="openDatePickerDialog()" />
<p id = "date">--</p>
Javascript :
function openDatePickerDialog() {
AndroidFunction.openDatePickerDialog();
}
function callFromActivity(date) {
document.getElementById('date').innerHTML = date;
}
My Activity :
public class MainActivity extends Activity {
WebView myBrowser;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myBrowser = (WebView)findViewById(R.id.mybrowser);
final MyJavaScriptInterface myJavaScriptInterface = new MyJavaScriptInterface(this);
myBrowser.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction");
myBrowser.getSettings().setJavaScriptEnabled(true);
myBrowser.loadUrl("file:///android_asset/test.html");
}
public class MyJavaScriptInterface
{
private int mYear;
private int mMonth;
private int mDay;
static final int DATE_DIALOG_ID = 0;
Context mContext;
MyJavaScriptInterface(Context c)
{
mContext = c;
}
public void openDatePickerDialog()
{
Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
//updateDisplay();
showDialog(DATE_DIALOG_ID);
}
private void updateDisplay() {
String date = new StringBuilder().append(mMonth + 1).append("-")
.append(mDay).append("-")
.append(mYear).append(" ").toString();
Toast.makeText(getApplicationContext(), date, Toast.LENGTH_LONG).show();
myBrowser.loadUrl("javascript:callFromActivity(\""+date+"\")");
}
private DatePickerDialog.OnDateSetListener mDateSetListener =
new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
updateDisplay();
}
};
protected Dialog onCreateDialog(int id) {
switch (id) {
case DATE_DIALOG_ID:
return new DatePickerDialog(MainActivity.this,
mDateSetListener,
mYear, mMonth, mDay);
}
return null;
}
}
}
Problem : I'am not getting DatePicker Dialog When i click on button. Where i'am going wrong ? Is my approach correct ?
Here is a sample code I use do show, derived from the code here:
In the html code, add 2 javascript functions:
// Fonction d'appel calendrier Android
function f_CallCalendar(Tag)
{
MSSAndroidFunction.openDatePickerDialog(Tag);
}
// Fonction de retour de la date
function callFromActivity_RetDate(Tag, data) {
document.Form.vDate.value = data;
}
The Tag is the id of the input form to be completed. You call the javascript functions like this:
<input name="vDate" type="text" size="11" />
<input name="Submit" type="button" onclick="f_CallCalendar('vDate')" value="Calendrier*" />
And here is the java code implemented. Note that the MyJavaScriptInterface is declared inside the MainActivity:
public class MainActivity extends Activity
implements TextWatcher{
WebView MainWebView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainWebView = (WebView)findViewById(R.id.main_webview);
MainWebView.getSettings().setJavaScriptEnabled(true);
final MyJavaScriptInterface myJavaScriptInterface = new MyJavaScriptInterface(this);
MainWebView.addJavascriptInterface(myJavaScriptInterface, "MyJavaScriptInterface");
}
// Classe de prise en charge du java privé
public class MyJavaScriptInterface
{
public String m_szTagId;
Context mContext;
MyJavaScriptInterface(Context c)
{
mContext = c;
}
public void openDatePickerDialog(String szTagId)
{
m_szTagId = szTagId;
Calendar c = Calendar.getInstance();
DatePickerDialog dp = new DatePickerDialog(mContext, new OnDateSetListener() {
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
String szDate = String.format("%02d/%02d/%04d", dayOfMonth, monthOfYear+1, year);
MainWebView.loadUrl("javascript:callFromActivity_RetDate(\""+m_szTagId+"\", \""+szDate+"\")");
} }, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
dp.show();
}
} // Class MyJavaScriptInterface
} // class MainActivity
Here is it. Hope this can help.
public void openDatePickerDialog()
{
Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
//updateDisplay();
DatePickerDialog dp = new DatePickerDialog(this,
mDateSetListener,
mYear, mMonth, mDay);
dp.show();
}
can you try this once.