This is html code.
<button class="rechangeMember">
Recharge
</button>
<script src="http://121.42.9.33:8080/statics/common/js/jquery.min.js"></script>
<script>
$(function(){
$('.rechangeMember').click(function(){
if(typeof myObj != 'undefined')
{
myObj.rechargeMember();
}
else
{
rechargeMember();
}
});
})
</script>
Then I want calling this button in Android, code below
member_level_show.getSettings().setJavaScriptEnabled(true);
member_level_show.getSettings().setDomStorageEnabled(true);
member_level_show.setWebChromeClient(new WebChromeClient());
member_level_show.addJavascriptInterface(new Recharge(), "rechargeMember");
member_level_show.loadUrl(Constants.URL_MEMBER_LEVEL + CurrentUserBean.getCurrentUser().getToken());
Recharge class
class Recharge{
#JavascriptInterface
private void rechargeMember() {
log("recharge");
}
}
then I click this button in webview, logcat is
"Uncaught ReferenceError: rechargeMember is not defined"
My code is error.
class Recharge{
#JavascriptInterface
private void rechargeMember() {
log("recharge");
}
}
should be changed to
class Recharge{
#JavascriptInterface
public void rechargeMember() {
log("recharge");
}
}
private can't be called outside, thank's for #Bemmu's comment.Second error is :
member_level_show.addJavascriptInterface(new Recharge(), "rechargeMember");
"rechargeMember" should be "myObj", JavaScript code is:
<script>
$(function(){
$('.rechangeMember').click(function(){
if(typeof myObj != 'undefined')
{
myObj.rechargeMember();
}
else
{
rechargeMember();
}
});
})
So Android function is called.
The name you specify in addJavaScriptInterface() becomes the name of the object. So you have to use
rechargeMember.rechargeMember();
Related
What I'm trying to do:
I made an alert function by spring which gives alert to user when the predetermined condition is fullfilled. This functions works well on Spring.
User can set several alerts on their own.
So when User presses "start alert" button in html, javascript sends get request using ajax depending on "idx" of alert on html.
Problem :
Seems like function is not working well on browser.
I did debug by using F12, I found out that Javascript is not getting any "idx" value..
So Nothing happens when I try to get alert.
All I wanna do is request by Alert id when button is pressed.
Here are my full code.
Controller
#GetMapping("/alerts/{id}")
#ResponseBody
public void AlertUser(#PathVariable Long id) {
alertService.AlertUser(id);
}
Service
public void AlertUser(Long id) {
Alert alert = alertRepository.findById(id).orElseThrow(() -> new NoSuchElementException());
double SetPrice = alert.getPrice();
String ticker = alert.getTicker();
JSONParser jsonParser = new JSONParser();
final NotificationRequest build = NotificationRequest.builder()
.title(ticker + " alert")
.message(SetPrice + "broke down")
.token(notificationService.getToken(userDetailService.returnUser().getEmail()))
.build();
try {
final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint();
Session session = clientEndPoint.connect(new URI("wss://ws.coincap.io/prices?assets=" + ticker));
WebsocketClientEndpoint.MessageHandler handler = new WebsocketClientEndpoint.MessageHandler() {
public void handleMessage(String message) throws ParseException, IOException {
Object obj = jsonParser.parse(message);
JSONObject jsonObject = (JSONObject) obj;
double price = Double.parseDouble(jsonObject.get(ticker).toString());
System.out.println("가격 : " + price);
if (price < SetPrice) {
System.out.println("끝");
notificationService.sendNotification(build);
session.close();
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.err.println("InterruptedException exception: " + ex.getMessage());
}
}
};
clientEndPoint.addMessageHandler(handler);
} catch (URISyntaxException ex) {
System.err.println("URISyntaxException exception: " + ex.getMessage());
}
}
**alert.mustache : {{#alerts}} ~ {{/alerts}} part is where problem occurs **
{{>layout/header}}
<form method="post" action="submitform" id="tickerSubmit">
<select name="contact" id="contact">
{{#tickers}}
<option value="{{.}}">{{.}}</option>
{{/tickers}}
</select>
<!-- <button type="submit" name="submit">Choose Ticker</button>-->
</form>
<div>
<input type="number" id = "price" placeholder="하한 금액을 입력하세요">
<input type="number" id = "percentage" placeholder="하한 퍼센트를 입력하세요">
<button type="button" class="btn btn-primary" id="alert-save-btn">알림 등록</button>
</div>
{{#alerts}}
<tr>
<div id = "idx">{{id}}</div>
<td><input type="submit" value="알림시작" id="alert-start"/></td>
<td>티커 : {{ticker}}</td>
<td>가격 : {{price}}</td>
</tr>
{{/alerts}}
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.9.2/firebase-messaging.js"></script>
<script src="/js/app/notification.js"></script>
{{>layout/footer}}
part of index.js encrypted in layout/footer
$('#alert-start').on('click', function() {
_this.alertStart();
});
},
alertStart : function() {
var idx = $('#idx').val();
$.ajax({
type: 'GET',
url: '/alerts/'+idx,
}).done(function() {
alert('알림이 시작됩니다.');
}).fail(function (error) {
alert(JSON.stringify('이거' + error));
});
},
Thanks in advance. any help or tip would be very helpful..
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;
using UnityEngine.UI;
public class admobVideo : MonoBehaviour {
RewardBasedVideoAd rewardBasedVideo;
static InterstitialAd interstitial;
string VideoID = "ca-app-pub-6032262586397129~2821965113";
string adUnitId = "ca-app-pub-6032262586397129/5003220953";
public static admobVideo Instance;
void Start ()
{
Instance = this;
DontDestroyOnLoad(gameObject);
RequestRewardBasedVideo();
RequestInterstitial();
}
public void RequestRewardBasedVideo()
{
rewardBasedVideo = RewardBasedVideoAd.Instance;
rewardBasedVideo.LoadAd(new AdRequest.Builder().Build(), adUnitId);
}
public void RequestInterstitial()
{
interstitial = new InterstitialAd(VideoID);
interstitial.LoadAd(new AdRequest.Builder().Build());
}
public void ShowAd()
{
if(rewardBasedVideo.IsLoaded())
{
rewardBasedVideo.Show();
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
}
}
public static void ShowInter()
{
showInterstitial(interstitial);
}
private void showAdd(RewardBasedVideoAd r)
{
if (r.IsLoaded())
{
//Subscribe to Ad event
r.Show();
r.OnAdRewarded += HandleRewardBasedVideoRewarded;
}
}
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
PlayerPrefs.SetInt("coins", PlayerPrefs.GetInt("coins") + 5);
GameObject.FindGameObjectWithTag("Coins").GetComponent<Text>().text = PlayerPrefs.GetInt("coins").ToString();
GameObject.FindGameObjectWithTag("Double").GetComponent<Button>().interactable = false;
Debug.Log("Pref: " + PlayerPrefs.GetInt("coins"));
}
static void showInterstitial(InterstitialAd i)
{
if (i.IsLoaded())
{
i.Show();
}
}
}
I am rewarding players with 5 coins , But when I click button nothing appears , I have tried to change code in many ways but no positive result.
when i click in the button in unity the console show me "Dummy is loaded" and "Dummy showrewardedbasedvideoad"
Method that is called upon button click is ShowAd(). Please Help
Please check by adding debug in HandleRewardBasedVideoRewarded method to check if it's called.
Also check you have added listener for that as you have not mentioned this in your code mentioned above.
rewardBasedVideo.OnAdRewarded += this.HandleRewardBasedVideoRewarded;
You have not initialised mobileAds with your app id:
MobileAds.Initialize();
For a project I am working on I need to inject javascript prior to any of the webpage document processing begins. This can easily be achieved via the WebBrowser component, but I am encountering difficulty using CefSharp.
Here is a simplification of the problem, a webpage needs an "InjectedObject" to be present to function. Calling the webpage without injection occurring at the very top of the document, or being evaluated/executed before the document is processed would result in:
=====html example output on failure=====
isObjectPresent?
false
=====
Where as I need the webpage to display:
=====html example output on success=====
isObjectPresent?
true
=====
<html>
<head>
<script>
isObjectPresent = typeof InjectedObject == "object";
</script>
</head>
<body>
<p>isObjectPresent?</p>
<div id="result"></div>
<script>
document.getElementById("result").innerHTML = isObjectPresent;
</script>
</body>
</html>
Looking at all the available suggestions would indicate I should use LoadingStateChanged() or FrameLoadEnd() to inject the script, ie:
public void OnFrameLoadEnd(object sender, FrameLoadEndEventArgs args) {
if (args.Frame.IsMain) {
args.Frame.ExecuteJavascriptAsync("window.InjectedObject = {};");
}
}
However all iterations I have tried of this, and even using FrameLoadStart, has resulted in the inserted javascript occurring after the document has begun processing. Is there any example of a true javascript injection insuring it occurs BEFORE document processing begins. (making sure to avoid a race condition/timing issue).
As an example of the WebBrowser component behavior that I am looking to imitate is:
private void uiWebBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
var browser = (WebBrowser)sender;
var document = browser.Document as HTMLDocument;
var head = document.getElementsByTagName("head").Cast<HTMLHeadElement>().First();
if (head != null)
{
var script = document.createElement("script") as IHTMLScriptElement;
script.text = "window.InjectedObject = {};"
if (head.firstChild != null)
{
head.insertBefore((IHTMLDOMNode)script, head.firstChild);
}
else
{
head.appendChild((IHTMLDOMNode)script;
}
}
}
Any help or suggestion is welcome, ideally I'd like to avoid downloading the page via an internet request parsing and inserting, and then using loadhtml, since I expect I would have to do that potentially for All navigation actions that impacted the main frame, which sounds like a hack job.
Following up from the comments it was suggested that the javascript V8 engine context was sufficient for the above use case. Attempting to implement the OnContextCreated method from the IRenderProcessMessageHandler interface has the same results.
==MainWindow.xaml==
<Window x:Class="ExampleCefSharp001.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
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:ExampleCefSharp001"
mc:Ignorable="d"
Title="MainWindow" Height="1000" Width="1100">
<Grid>
<cefSharp:ChromiumWebBrowser x:Name="uiWebView"></cefSharp:ChromiumWebBrowser>
</Grid>
</Window>
==MainWindow.xaml.cs==
public partial class MainWindow : Window
{
JavascriptManager jsmanager;
public MainWindow()
{
InitializeComponent();
jsmanager = new JavascriptManager(uiWebView);
}
}
public class JavascriptManager : ILoadHandler, IRenderProcessMessageHandler
{
string injection = "window.InjectedObject = {};";
public JavascriptManager(ChromiumWebBrowser browser)
{
browser.LoadHandler = this;
browser.RenderProcessMessageHandler = this;
// Lets just pretend this is a real url with the example html above.
browser.Address = "https://www.example.com/timingtest.htm"
}
public void OnContextCreated(IWebBrowser browserControl, IBrowser browser, IFrame frame)
{
frame.ExecuteJavaScriptAsync(injection);
}
}
I do appreciate the comments and suggestions. If there is something I am missing please let me know!
Finally got back to this. Heavily based on example found in: CefSharp.Example/Filters/FindReplaceResponseFilter.cs
implementing the IRequestHandler and IResponseFilter interfaces:
==MainWindow.xaml==
<Window x:Class="ExampleCefSharp001.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
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:ExampleCefSharp001"
mc:Ignorable="d"
Title="MainWindow" Height="1000" Width="1100">
<Grid>
<cefSharp:ChromiumWebBrowser x:Name="uiWebView"></cefSharp:ChromiumWebBrowser>
</Grid>
</Window>
==MainWindow.xaml.cs==
public partial class MainWindow : Window
{
JavascriptManager jsmanager;
public MainWindow()
{
InitializeComponent();
jsmanager = new JavascriptManager(uiWebView);
}
}
public class JavascriptManager : IRequestHandler
{
string injection = "window.InjectedObject = {};";
public JavascriptManager(ChromiumWebBrowser browser)
{
browser.RequestHandler = this;
// Lets just pretend this is a real url with the example html above.
browser.Address = "https://www.example.com/timingtest.htm"
}
public IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
if (frame.IsMain && request.ResourceType == ResourceType.MainFrame)
{
return new JavascriptInjectionFilter(injection);
}
return null;
}
}
public class JavascriptInjectionFilter : IResponseFilter
{
/// <summary>
/// Location to insert the javascript
/// </summary>
public enum Locations
{
/// <summary>
/// Insert Javascript at the top of the header element
/// </summary>
head,
/// <summary>
/// Insert Javascript at the top of the body element
/// </summary>
body
}
string injection;
string location;
int offset = 0;
List<byte> overflow = new List<byte>();
/// <summary>
/// Constructor
/// </summary>
/// <param name="injection"></param>
/// <param name="location"></param>
public JavascriptInjectionFilter(string injection, Locations location = Locations.head)
{
this.injection = "<script>" + injection + "</script>";
switch (location)
{
case Locations.head:
this.location = "<head>";
break;
case Locations.body:
this.location = "<body>";
break;
default:
this.location = "<head>";
break;
}
}
/// <summary>
/// Disposal
/// </summary>
public void Dispose()
{
//
}
/// <summary>
/// Filter Processing... handles the injection
/// </summary>
/// <param name="dataIn"></param>
/// <param name="dataInRead"></param>
/// <param name="dataOut"></param>
/// <param name="dataOutWritten"></param>
/// <returns></returns>
public FilterStatus Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
{
dataInRead = dataIn == null ? 0 : dataIn.Length;
dataOutWritten = 0;
if (overflow.Count > 0)
{
var buffersize = Math.Min(overflow.Count, (int)dataOut.Length);
dataOut.Write(overflow.ToArray(), 0, buffersize);
dataOutWritten += buffersize;
if (buffersize < overflow.Count)
{
overflow.RemoveRange(0, buffersize - 1);
}
else
{
overflow.Clear();
}
}
for (var i = 0; i < dataInRead; ++i)
{
var readbyte = (byte)dataIn.ReadByte();
var readchar = Convert.ToChar(readbyte);
var buffersize = dataOut.Length - dataOutWritten;
if (buffersize > 0)
{
dataOut.WriteByte(readbyte);
dataOutWritten++;
}
else
{
overflow.Add(readbyte);
}
if (char.ToLower(readchar) == location[offset])
{
offset++;
if (offset >= location.Length)
{
offset = 0;
buffersize = Math.Min(injection.Length, dataOut.Length - dataOutWritten);
if (buffersize > 0)
{
var data = Encoding.UTF8.GetBytes(injection);
dataOut.Write(data, 0, (int)buffersize);
dataOutWritten += buffersize;
}
if (buffersize < injection.Length)
{
var remaining = injection.Substring((int)buffersize, (int)(injection.Length - buffersize));
overflow.AddRange(Encoding.UTF8.GetBytes(remaining));
}
}
}
else
{
offset = 0;
}
}
if (overflow.Count > 0 || offset > 0)
{
return FilterStatus.NeedMoreData;
}
return FilterStatus.Done;
}
/// <summary>
/// Initialization
/// </summary>
/// <returns></returns>
public bool InitFilter()
{
return true;
}
}
Thanks to amaitland for pointing me in the right direction, and for the sample program that the vast majority of the above code was based on. End result:
<html><head></head><body><script>window.InjectedObject = {}</script>
<script>
isObjectPresent = typeof InjectedObject == "object";
</script>
<p>isObjectPresent?</p>
<div id="result"></div>
<script>
document.getElementById("result").innerHTML = isObjectPresent;
</script>
</body></html>
Which meets my needs of pre-processing the document with some text at the top of the header ensuring no timing issues where existing code might be run before the injected code.
edit
couple small fixes. added control logic to only insert when a mainframe is loaded.
Well your answer is correct that you should override the implementation of GetResourceResponseFilter but in case you didn't implement the interface in a correct way you will end up with browser not rendering content, you can instead inherit the DefaultRequestHandler and override the GetResourceResponseFilter() and provide the custom filter as mentioned in the accepted answer, this will be easier in case you need only to ovveride this specific functionality :
public class CustomRequestHandler : DefaultRequestHandler
{
string script = "alert('hello');";
public override IResponseFilter GetResourceResponseFilter(CefSharp.IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
if (frame.IsMain && request.ResourceType == ResourceType.MainFrame)
{
return new JavascriptInjectionFilter(script);
}
return null;
}
}
Then assign it to the chromium browser:
CustomRequestHandler customRequestHandler = new CustomRequestHandler();
chromeBrowser.RequestHandler = customRequestHandler ;
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.