Java tutorial
/** * Copyright 2014 AppLift GmbH * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.applift.api.tester.activity; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import org.droidparts.annotation.inject.InjectBundleExtra; import org.droidparts.annotation.inject.InjectView; import org.droidparts.concurrent.task.AsyncTaskResultListener; import org.droidparts.net.http.HTTPResponse; import org.droidparts.util.L; import org.json.JSONObject; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.RadioButton; import com.applift.api.sdk.Contract; import com.applift.api.sdk.model.Ad; import com.applift.api.sdk.model.AdFormat; import com.applift.api.sdk.model.ImageAd; import com.applift.api.sdk.model.NativeAd; import com.applift.api.sdk.task.SendConfirmationTask; import com.applift.api.sdk.util.WebRedirector; import com.applift.api.tester.R; import com.applift.api.tester.adapter.AbstractRenderedResponseAdapter; import com.applift.api.tester.adapter.ImageFormatResponseAdapter; import com.applift.api.tester.adapter.NativeFormatResponseAdapter; public class RenderedResponseActivity extends AbstractResponseActivity implements Contract, OnScrollListener, OnItemClickListener { private static final String FORMAT = "format"; public static Intent getIntent(Context ctx, AdFormat format, JSONObject obj) { Intent intent = new Intent(ctx, RenderedResponseActivity.class); intent.putExtra(FORMAT, format); fillIntent(intent, obj); return intent; } @InjectBundleExtra(key = FORMAT) private AdFormat format; private ArrayList<? extends Ad> ads; @InjectView(id = R.id.rb_redirect_background) private RadioButton backgroundRedirectRB; @InjectView(id = R.id.rb_redirect_browser) private RadioButton browserRedirectRB; @InjectView(id = android.R.id.list) private ListView listView; private AbstractRenderedResponseAdapter<? extends Ad> adapter; private Handler confirmHandler; @Override public void onPreInject() { setContentView(R.layout.activity_rendered_response); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); confirmHandler = new Handler(); try { ads = Ad.parseAds(this, format, json); } catch (Exception e) { L.wtf(e); return; } if (format == AdFormat.NATIVE) { adapter = new NativeFormatResponseAdapter(this, (List<NativeAd>) ads); } else { adapter = new ImageFormatResponseAdapter(this, (List<ImageAd>) ads); } backgroundRedirectRB.setChecked(true); listView.setAdapter(adapter); listView.setOnScrollListener(this); listView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Ad ad = adapter.getItem(position); WebRedirector r = new WebRedirector(this, ad.clickUrl); if (backgroundRedirectRB.isChecked()) { r.doBackgroundRedirect(); } else { r.doBrowserRedirect(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { confirmHandler.removeMessages(0); confirmHandler.postDelayed(submitConfirmationRunnable, CONFIRMATION_DELAY); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // pass } // private static final int CONFIRMATION_DELAY = 1000; private final Runnable submitConfirmationRunnable = new Runnable() { @Override public void run() { confirmShownAds(); } }; private void confirmShownAds() { int first = 0; int last = (listView.getChildCount() - 1); while (listView.getChildAt(first).getTop() < 0) { first++; } while (listView.getChildAt(last).getBottom() > listView.getHeight()) { last--; } int firstPos = listView.getFirstVisiblePosition() + first; int lastPos = firstPos + (last - first); for (int pos = firstPos; pos <= lastPos; pos++) { Ad ad = adapter.getItem(pos); if (!confirmedAds.contains(ad)) { confirmedAds.add(ad); new SendConfirmationTask(this, resultListener, ad).execute(); } } } private final HashSet<Ad> confirmedAds = new HashSet<>(); private static final AsyncTaskResultListener<HTTPResponse> resultListener = new AsyncTaskResultListener<HTTPResponse>() { @Override public void onAsyncTaskSuccess(HTTPResponse resp) { L.i(resp); } @Override public void onAsyncTaskFailure(Exception ex) { L.w(ex); } }; }