我正在尝试将2个android studio项目合并为一个。 这是我的app level build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.cricketbuzz"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable true
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.github.JakeWharton:ViewPagerIndicator:2.4.1@aar'
compile 'com.android.support:multidex:1.0.0'
compile 'com.cricketbuzzsdk:CricketBuzzSDK:1.0.0'
compile 'com.wang.avi:library:2.1.3'
compile project(':basketball')
}
这是我的库build.gradle
apply plugin: 'com.android.library'
android {
signingConfigs {
config {
}
}
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
// applicationId "com.gmail.jorgegilcavazos.ballislife"
minSdkVersion 19
targetSdkVersion 23
versionCode 3
versionName "0.1.0"
signingConfig signingConfigs.config
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/LICENCE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE.txt'
}
productFlavors {
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.1.2'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.mcxiaoke.volley:library:1.0.19'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.google.android.gms:play-services-gcm:8.3.0'
compile 'com.android.support:design:23.4.0'
compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:recyclerview-v7:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.android.support:customtabs:23.3.0'
compile 'net.dean.jraw:JRAW:0.9.0'
compile 'com.google.code.gson:gson:2.7'
compile 'com.jakewharton:butterknife:8.4.0'
}
我得到的错误是:
C:\用户\ karanc \ AndroidStudioProjects \ CricketBuzz \篮球\ SRC \主\的java \ COM \的Gmail \ jorgegilcavazos \ ballislife \设有\游戏\ GameAdapter.java 错误:(112,23)错误:元素值必须是常量表达式
C:\用户\ karanc \ AndroidStudioProjects \ CricketBuzz \篮球\ SRC \主\的java \ COM \的Gmail \ jorgegilcavazos \ ballislife \特征\ gamethread \ CommentThreadFragment.java 错误:(127,22)错误:需要持续表达
以下是GameAdapter& CommentThread文件: GameAdapter.java
package com.gmail.jorgegilcavazos.ballislife.features.games;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.gmail.jorgegilcavazos.ballislife.features.data.NbaGame;
import com.gmail.jorgegilcavazos.ballislife.R;
import com.gmail.jorgegilcavazos.ballislife.util.Utilities;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import static android.support.design.R.styleable.RecyclerView;
/**
* RecyclerView Adapter used by the {@link GamesFragment} to display a list of games.
*/
public class GameAdapter extends RecyclerView.Adapter<GameAdapter.GameViewHolder> {
private Context context;
private List<NbaGame> nbaGameList;
private GamesFragment.GameItemListener gameItemListener;
public GameAdapter(List<NbaGame> nbaGames,
GamesFragment.GameItemListener itemListener) {
nbaGameList = nbaGames;
gameItemListener = itemListener;
}
@Override
public GameViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_game,
parent, false);
context = parent.getContext();
return new GameViewHolder(view);
}
@Override
public void onBindViewHolder(final GameViewHolder holder, int position) {
NbaGame nbaGame = nbaGameList.get(position);
int resKeyHome = context.getResources().getIdentifier(nbaGame.getHomeTeamAbbr()
.toLowerCase(), "drawable", context.getPackageName());
int resKeyAway = context.getResources().getIdentifier(nbaGame.getAwayTeamAbbr()
.toLowerCase(), "drawable", context.getPackageName());
holder.tvHomeTeam.setText(nbaGame.getHomeTeamAbbr());
holder.tvAwayTeam.setText(nbaGame.getAwayTeamAbbr());
holder.ivHomeLogo.setImageResource(resKeyHome);
holder.ivAwayLogo.setImageResource(resKeyAway);
holder.tvHomeScore.setText(nbaGame.getHomeTeamScore());
holder.tvAwayScore.setText(nbaGame.getAwayTeamScore());
holder.tvClock.setText(nbaGame.getGameClock());
holder.tvPeriod.setText(Utilities.getPeriodString(nbaGame.getPeriodValue(),
nbaGame.getPeriodName()));
holder.tvHomeScore.setVisibility(View.GONE);
holder.tvAwayScore.setVisibility(View.GONE);
holder.tvClock.setVisibility(View.GONE);
holder.tvPeriod.setVisibility(View.GONE);
holder.tvFinal.setVisibility(View.GONE);
holder.tvTime.setVisibility(View.GONE);
switch (nbaGame.getGameStatus()) {
case NbaGame.PRE_GAME:
holder.tvTime.setVisibility(View.VISIBLE);
holder.tvTime.setText(nbaGame.getPeriodStatus());
break;
case NbaGame.IN_GAME:
holder.tvHomeScore.setVisibility(View.VISIBLE);
holder.tvAwayScore.setVisibility(View.VISIBLE);
holder.tvClock.setVisibility(View.VISIBLE);
holder.tvPeriod.setVisibility(View.VISIBLE);
break;
case NbaGame.POST_GAME:
holder.tvHomeScore.setVisibility(View.VISIBLE);
holder.tvAwayScore.setVisibility(View.VISIBLE);
holder.tvFinal.setVisibility(View.VISIBLE);
holder.tvFinal.setText("FINAL");
break;
}
holder.container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
gameItemListener.onGameClick(nbaGameList.get(holder.getAdapterPosition()));
}
});
}
@Override
public int getItemCount() {
return null != nbaGameList ? nbaGameList.size() : 0;
}
public void swap(List<NbaGame> data) {
nbaGameList.clear();
nbaGameList.addAll(data);
notifyDataSetChanged();
}
public static class GameViewHolder extends RecyclerView.ViewHolder {
View container;
@BindView(R.id.homelabel) TextView tvHomeTeam;
@BindView(R.id.awaylabel) TextView tvAwayTeam;
@BindView(R.id.homescore) TextView tvHomeScore;
@BindView(R.id.awayscore) TextView tvAwayScore;
@BindView(R.id.clock) TextView tvClock;
@BindView(R.id.period) TextView tvPeriod;
@BindView(R.id.extraLabel) TextView tvTime;
@BindView(R.id.extraLabel2) TextView tvFinal;
@BindView(R.id.homeicon) ImageView ivHomeLogo;
@BindView(R.id.awayicon) ImageView ivAwayLogo;
public GameViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
container = view;
}
}
}
CommentThread.java
package com.gmail.jorgegilcavazos.ballislife.features.gamethread;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import com.gmail.jorgegilcavazos.ballislife.features.shared.CommentAdapter;
import com.gmail.jorgegilcavazos.ballislife.R;
import com.gmail.jorgegilcavazos.ballislife.util.AuthListener;
import com.gmail.jorgegilcavazos.ballislife.util.MyDebug;
import com.gmail.jorgegilcavazos.ballislife.network.RedditAuthentication;
import com.gmail.jorgegilcavazos.ballislife.util.RedditUtils;
import net.dean.jraw.http.SubmissionRequest;
import net.dean.jraw.models.CommentNode;
import net.dean.jraw.models.CommentSort;
import net.dean.jraw.models.Listing;
import net.dean.jraw.models.Submission;
import net.dean.jraw.paginators.Sorting;
import net.dean.jraw.paginators.SubredditPaginator;
import java.util.ArrayList;
import java.util.List;
public class CommentThreadFragment extends Fragment {
private static final String TAG = "CommentThreadFragment";
public interface SubmissionListingFetchListener {
void onSuccess(Listing<Submission> submissions);
void onFailure(String message);
}
public interface FullSubmissionFetchListener {
void onSuccess(Submission submission);
void onFailure(String message);
}
public static final String HOME_TEAM_KEY = "HOME_TEAM";
public static final String AWAY_TEAM_KEY = "AWAY_TEAM";
public static final String THREAD_TYPE_KEY = "THREAD_TYPE";
private static final String NBA_SUBREDDIT = "nba";
private static final int SEARCH_LIMIT = 100;
private static final int RETRY_FIND_SUBMISSION = 0;
private static final int RETRY_FETCH_COMMENTS = 1;
private String mHomeTeam;
private String mAwayTeam;
private String mThreadId;
private boolean mFoundThreadId;
private RedditUtils.GameThreadType mThreadType;
Context mContext;
View rootView;
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
CommentAdapter mCommentAdapter;
ProgressBar mProgressBar;
Snackbar mSnackbar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mHomeTeam = getArguments().getString(HOME_TEAM_KEY);
mAwayTeam = getArguments().getString(AWAY_TEAM_KEY);
mThreadType = (RedditUtils.GameThreadType) getArguments().get(THREAD_TYPE_KEY);
}
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_comment_thread, container, false);
mProgressBar = (ProgressBar) rootView.findViewById(R.id.progressBar);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.comment_thread_rv);
mLayoutManager = new LinearLayoutManager(mContext);
mRecyclerView.setLayoutManager(mLayoutManager);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mRecyclerView.setNestedScrollingEnabled(false);
} else {
ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);
}
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContext = getActivity();
if (mFoundThreadId) {
fetchComments();
} else {
findGameSubmission();
}
}
@Override
public void onPause() {
dismissSnackbar();
super.onPause();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
dismissSnackbar();
if (mFoundThreadId) {
fetchComments();
} else {
findGameSubmission();
}
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Starts a {@link FetchSubmissionListing} task that retrieves a list of submissions in the
* /r/nba subreddit. If it is successfully retrieved, it tries to find the one that belongs
* to this game and shows its comment tree.
*/
private void findGameSubmission() {
AuthListener authListener = new AuthListener() {
@Override
public void onSuccess() {
findGameSubmission();
}
@Override
public void onFailure() {
showSnackBar("Failed to connect to Reddit", true, RETRY_FIND_SUBMISSION);
}
};
SubmissionListingFetchListener fetchListener = new SubmissionListingFetchListener() {
@Override
public void onSuccess(Listing<Submission> submissions) {
mThreadId = RedditUtils.findNbaGameThreadId(submissions, mThreadType,
mHomeTeam, mAwayTeam);
if (mThreadId != null) {
mFoundThreadId = true;
fetchComments();
} else {
mFoundThreadId = false;
showSnackBar("No comment thread found", true, RETRY_FIND_SUBMISSION);
}
}
@Override
public void onFailure(String message) {
showSnackBar(message, true, RETRY_FIND_SUBMISSION);
}
};
new FetchSubmissionListing(mContext, NBA_SUBREDDIT, SEARCH_LIMIT, Sorting.NEW,
fetchListener, authListener).execute();
}
/**
* Starts a {@link FetchFullSubmission} task that retrieves the Submission of the given
* submissionId. A "full" submissions is one that also contains its comment tree.
*/
private void fetchComments() {
AuthListener authListener = new AuthListener() {
@Override
public void onSuccess() {
fetchComments();
}
@Override
public void onFailure() {
showSnackBar("Failed to connect to Reddit", true, RETRY_FETCH_COMMENTS);
}
};
FullSubmissionFetchListener fetchListener = new FullSubmissionFetchListener() {
@Override
public void onSuccess(Submission submission) {
loadComments(submission);
}
@Override
public void onFailure(String message) {
showSnackBar(message, true, RETRY_FIND_SUBMISSION);
}
};
new FetchFullSubmission(mContext, mThreadId, fetchListener, authListener).execute();
}
/**
* Loads a tree of comments into the RecyclerView, given a Reddit Submission.
*/
private void loadComments(Submission submission) {
Iterable<CommentNode> iterable = submission.getComments().walkTree();
List<CommentNode> commentNodes = new ArrayList<>();
for (CommentNode node : iterable) {
commentNodes.add(node);
}
mCommentAdapter = new CommentAdapter(mContext, commentNodes);
mRecyclerView.setAdapter(mCommentAdapter);
}
private void showSnackBar(String message, boolean retry, final int retryCode) {
mSnackbar = Snackbar.make(rootView, message,
Snackbar.LENGTH_INDEFINITE);
if (retry) {
mSnackbar.setAction("RETRY", new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (retryCode) {
case RETRY_FIND_SUBMISSION:
findGameSubmission();
break;
case RETRY_FETCH_COMMENTS:
fetchComments();
break;
}
}
});
}
mSnackbar.show();
mProgressBar.setVisibility(View.GONE);
}
private void dismissSnackbar() {
if (mSnackbar != null && mSnackbar.isShown()) {
mSnackbar.dismiss();
}
}
/**
* Retrieves a Listing of Reddit Submissions, given a subreddit, a limit of submissions and a
* sorting option.
*/
private class FetchSubmissionListing extends AsyncTask<Void, Void, Listing<Submission>> {
private Context mContext;
private String mSubreddit;
private int mLimit;
private Sorting mSorting;
private SubmissionListingFetchListener mFetchListener;
private AuthListener mAuthListener;
public FetchSubmissionListing(Context context, String subreddit, int limit, Sorting sorting,
SubmissionListingFetchListener fetchListener,
AuthListener authListener) {
mContext = context;
mSubreddit = subreddit;
mLimit = limit;
mSorting = sorting;
mFetchListener = fetchListener;
mAuthListener = authListener;
}
@Override
protected void onPreExecute() {
mProgressBar.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
}
@Override
protected Listing<Submission> doInBackground(Void... params) {
RedditAuthentication redditAuthentication = RedditAuthentication.getInstance();
if (redditAuthentication.getRedditClient().isAuthenticated()) {
SubredditPaginator paginator = new SubredditPaginator(
redditAuthentication.getRedditClient(), mSubreddit);
paginator.setLimit(mLimit);
paginator.setSorting(mSorting);
try {
return paginator.next(false /* forceNetwork */);
} catch (Exception e) {
if (MyDebug.LOG) {
Log.d(TAG, "Reddit auth error on FetchSubmissionListing.");
}
}
} else {
mFetchListener.onFailure("Failed to connect to Reddit");
}
return null;
}
@Override
protected void onPostExecute(Listing<Submission> submissions) {
if (submissions != null) {
mFetchListener.onSuccess(submissions);
} else {
if (!RedditAuthentication.getInstance().getRedditClient().isAuthenticated()) {
// Attempt to authenticate once.
RedditAuthentication.getInstance().authenticate(mContext, mAuthListener);
}
mFetchListener.onFailure("Failed to connect to Reddit");
}
}
}
/**
* Retrieves a "full" Reddit submission given a Reddit submisisonId. A "full" submission is one
* that also contains its comment tree.
* The sorting of the thread is determined by mThreadType (Live game or post game).
*/
private class FetchFullSubmission extends AsyncTask<Void, Void, Submission> {
private Context mContext;
private String mThreadId;
private FullSubmissionFetchListener mFetchListener;
private AuthListener mAuthListener;
public FetchFullSubmission(Context context, String threadId,
FullSubmissionFetchListener fetchListener,
AuthListener authListener) {
mContext = context;
mThreadId = threadId;
mFetchListener = fetchListener;
mAuthListener = authListener;
}
@Override
protected void onPreExecute() {
mProgressBar.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
}
@Override
protected Submission doInBackground(Void... params) {
if (mThreadId == null) {
return null;
}
SubmissionRequest.Builder builder = new SubmissionRequest.Builder(mThreadId);
switch (mThreadType) {
case LIVE_GAME_THREAD:
builder.sort(CommentSort.NEW);
break;
case POST_GAME_THREAD:
builder.sort(CommentSort.TOP);
break;
default:
builder.sort(CommentSort.TOP);
break;
}
SubmissionRequest submissionRequest = builder.build();
try {
return RedditAuthentication.getInstance()
.getRedditClient().getSubmission(submissionRequest);
} catch (Exception e) {
if (MyDebug.LOG) {
Log.d(TAG, "Could not load submission in FetchFullSubmission.");
}
}
return null;
}
@Override
protected void onPostExecute(Submission submission) {
mProgressBar.setVisibility(View.GONE);
if (submission != null) {
mFetchListener.onSuccess(submission);
mRecyclerView.setVisibility(View.VISIBLE);
} else {
if (!RedditAuthentication.getInstance().getRedditClient().isAuthenticated()) {
// Attempt to re-authenticate once.
RedditAuthentication.getInstance().authenticate(mContext, mAuthListener);
}
mFetchListener.onFailure("Failed to connect to Reddit");
}
}
}
}
如何摆脱这个?
答案 0 :(得分:3)
经过这么多挖掘,我找到了解决方案。 图书馆项目:
要在库中使用黄油刀,请将插件添加到您的buildscript中:
buildscript {
repositories {
mavenCentral()
google()
}
dependencies {
classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
}
}
,然后将其应用到您的模块中:
apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
现在请确保在所有黄油刀注释中使用R2而不是R。
class ExampleActivity extends Activity {
@BindView(R2.id.user) EditText username;
@BindView(R2.id.pass) EditText password;
...
}
答案 1 :(得分:1)
正如对此github issue所指出的,当我们在图书馆项目中使用Butterknife时,可以通过使用R2.id而不是R.id来工作。
答案 2 :(得分:0)
您已在图书馆项目中实施了Butterknife。 Butterknife不适用于图书馆项目。有关详细信息,您可以点击此链接 https://github.com/JakeWharton/butterknife/issues/45